Vous êtes sur la page 1sur 20

You are here: Home

Tutorials

Tutorial 1

Main
Home Tutorials Tutorial 1 Tutorial 2 Tutorial 3 About

How to remotely control an Arduino from a PC - Part 1 1. Overview 2. The hardware 3. Setup 3.1 The local unit 3.2 The remote unit 4. The software 4.1 The PC program 4.2 The Arduino program 5. Video

6. Downloads Appendix A Appendix B All Pages

How to remotely control an Arduino from a PC - Part 1 In this tutorial we will learn how to remotely control an Arduino board from a PC using a pair of APC 220 Radio Frequency (RF) modules. We will start by setting up the RF link and then build a a simple demo application to test it. The Arduino is a prototyping board built around the Atmel AVR microcontroller. It is designed for enthusiasts and has many applications in robotics: it can be used for example to control DC motors, servos, LCD displays and several other devices. It is my preferred platform for prototyping because it is inexpensive, sturdy, error-tolerant (mine is still working after multiple short-circuits and accidental overloads), easy to set up and compatible with a large number of add-on devices. The APC 220 is one among many RF modules that can be installed on the Arduino. I have selected it for this tutorial instead of some perhaps better-known devices such as the XBee mainly because of its ease of use. While the APC has some limitations compared to the XBee (for example, it can only control a remote device at once), it is nonetheless a powerful platform, and it is cheaper. This tutorial is divided into two parts. In this first part, we will learn how to configure the APC modules and set up the RF connection. We will then build a test system using a PC, an Arduino and a pair of LEDs, and write a simple program to turn them on and off remotely. In part two, we will replace the LEDs with a Direct Current (DC) motor and build a program to control its speed and direction of rotation. You may easily apply the type of setup described in this tutorial to your own robotics projects, swapping the LEDs or the DC motor with any other devices, such as servos, robotic arms, sensors or video displays. The contents are presented as follows. The "Overview" section describes the system that we are going to build and explains briefly how it works. It also describes the RF communications protocol that we are going to use. The "Hardware" section lists the required parts, while the "Setup" section shows how to assemble them. The "Software" section examines the program's source code, commenting the most relevant snippets. Much of the hardware and software will be reused in part two. The "Video" section shows a video of the working system, and the "Downloads" section links to the source code. Finally, Appendix A explains how to install and configure the software for the Arduino, while Appendix B does the same for the APC. The source code is distributed under the LGPL 2.1 software license. The following disclaimer covers both this tutorial and the software provided. For any feedback and corrections, please send emails to this address This email address is being protected from spambots. You need JavaScript enabled to view it. .

1. Overview
The system that we are going to build is composed of two parts: a local unit, which includes the PC and one APC module, and a remote unit, which includes the other APC, the Arduino and the LEDs (a red and a green one). In a real-world application, the remote unit could be a robot or any kind of moving mechanical part. In this tutorial, the APC on the local unit is used exclusively as a transmitter, and the one on the remote unit as a receiver.

Figure 1: System diagram.

To operate this apparatus, two software programs need to be installed and run, one on the PC and one on the Arduino. The PC program is a Java application which takes the user's commands (i.e., turn either LED on or off) and sends them out to the remote unit. The program running on the Arduino parses the commands and executes them. The two LEDs are placeholders for the DC motor that will be used in the second part of the tutorial. The green LED simulates the motor spinning forward, the red one in reverse, and when both LEDs are off the motor is considered to be at rest. Also, the LEDs cannot be both on at the same time. The two programs use a naming convention consistent with this motor analogy, so as to make the code easier to reuse in part two. For example, the Java application's main window has a label that describes the state of the system as being either FORWARD, REVERSE or at REST. The Arduino code uses a similar naming pattern. The communications protocol between the local and the remote units consists of three different instructions, which are encoded as 8-bit ASCII characters: set the motor in the FORWARD state (encoded as '0'), in the REVERSE state ('1') or to REST ('2'). Communications are kept one-way only, from the local to the remote unit. The transmission rate set to 9600 baud. This simple protocol will do for this demo, but it can become inadequate if there is no guarantee of clear reception or data integrity. To avoid these issues, the communications protocol could be improved on a real-world setup by implementing some sort of acknowledgment message from the remote unit, so that the PC could keep track of each command it sends out. Also, if the remote unit were installed on a moving vehicle, it may happen to fall outside the transmission range. To avoid getting lost, the remote unit could periodically poll the PC for status updates, and if it received no reply all of a sudden, it could then attempt to move the vehicle back within range by backtracking to a previous location.

2. The hardware
One Arduino board (an additional one is optional) The Arduino is a prototyping board built around the Atmel AVR microcontroller. If you are not familiar with this platform, Appendix A will guide you in setting it up. I picked the Arduino for this tutorial because I find it very easy and intuitive to use. In fact, once you have connected the board to a PC and installed its drivers, you are only a few clicks away from running your first program. The Arduino website provides a lot of documentation on how to set up the board and write programs for it; there is also a large community of enthusiasts who have published many tutorials for this platform, ranging from beginner's guides to advanced projects. In this tutorial, we need one board for the remote unit. Here, I use a DFRduino Romeo model, an Arduino clone that has some additional on-board components, including an Hbridge and connectors for two DC motors and one APC 220 module. We will use the Hbridge and the motor connectors in part two of this tutorial. If your Arduino model does not include them, you will have to add them through a separate plug-in board, also known as a shield.

Figure 2: DFRduino Romeo board with the APC 220 module plugged in. The Arduino is powered here by a 9 V battery. If you have a spare Arduino on hand, you may use it to connect the APC transmitter module

to the PC. A pair of APC 220 transmitter/receiver units The APC 220 is an RF module that can be used both as a transmitter and a receiver. Appendix B provides more documentation on how to install and configure this device.

Figure 3: From left to right, a USB-to-UART adapter and two APC 220 modules. Some Arduino models, like the Romeo above, have on-board connectors for APC 220 modules. Some others do not, including the Arduino base model (the Uno). If your board has no fitting connector, you will have to hand-wire the APC using a breadboard. To connect the APC transmitter to your PC, you need a USB-to-UART adapter similar to the one in the picture above. Retailers usually bundle one of these to each pair of APC modules, though you can also purchase them separately. If do not have one on hand, you may use a spare Arduino board instead. In this case, you must connect the TX and RX lines on the board to those on the APC straight-through, as opposed to crossing them over (see the next section for more details). You will still need an adapter, however, to configure the APC modules the first time you use them. The configuration process is described in detail in Appendix B. Briefly, it involves connecting the two modules to a PC and then running an application called Rf-Magic to make sure that they use the same operating frequency, transmission rate and parity check mode. Unfortunately, Rf-Magic will not recognize a device unless it is plugged in through a proper adapter. APC pairs that are left unconfigured may broadcast on frequencies that you are not allowed to use in your country, or just not work together at all if they have mismatches settings. Configuring a pair of twin APCs is a one-time operation, and once you have done it you can go back to using an Arduino. A 9 V battery and adapter (optional) The battery is for supplying power to the remote unit. The next section shows an alternative setup where the remote unit draws power from the local one. The Arduino documentation recommends a power source between 9 and 12 V and a minimum current rating of 250 mA. A 9 V battery provides sufficient power for the purpose of this tutorial, but it may be inadequate if additional components are connected to the Arduino. 2LEDs I use here a green LED to simulate the motor rotating forward and a red one for reverse. 222 k resistances The purpose of the resistances is to limit the current going into the LEDs. A breadboard Wires

Figure 4: Additional hardware. From left to right, top to bottom: a breadboard, LEDs, resistors, wires, a 9 V battery with a connector for the Arduino.

3. Setup
This section explains how to assemble the hardware. It describes many possible wiring layouts, both for the local and the remote unit.

Figure 5: Top view of the complete setup. An Arduino board is used connect the PC to the transmitter module. The remote unit is powered by a 9 V battery.

3.1 The local unit


Base setup Simply plug the APC transmitter into the PC using the USB-to-UART adapter. Make sure that the APC is properly installed and configured (see Appendix B).

Figure 6: APC 220 unit plugged into the PC's USB port through the adapter. Setup with a spare Arduino board If you do not have an adapter, you can use a spare Arduino instead. Figure 7 shows a schematic diagram of the cabling, while Figure 8 shows a picture of the complete system.

Figure 7: Cabling diagram of the local unit with Arduino.

Figure 8: Picture of the complete local unit with Arduino. Using the breadboard, connect the 5 V and GND power terminals on the Arduino to the corresponding pins of the APC. Next, wire up the serial bus pins (marked RX and TX) on the two devices. You will need to connect them straight-through (the TX pin on the Arduino to the TX pin on the APC and vice versa), as opposed to crossing them over (RX into TX). When connecting a device to the Arduino, it is important to know whether to apply a straightthrough or a crossover layout. The crossover configuration is by far the most common and needs to be used when the device connects directly to the microcontroller on the Arduino, as shown in Figure 9.

Figure 9: Diagram of a crossover connection between the APC module and the AVR microcontroller on an Arduino board. Both devices have a TX and an RX pin, respectively to transmit and receive data. The controller pins match the connectors of the same name on the Arduino board. In order to broadcast data, the controller sends it out to the APC from its TX pin. The APC receives the data on its RX pin and then relays it to the antenna for broadcasting. Conversely, when the APC receives data from its antenna, it relays it to the controller using the opposite pins. On the local unit, however, the APC bypasses the microcontroller and connects to the PC bus instead. The straight-through layout is therefore the correct configuration (see Figure 10).

Figure 10: Diagram of a straight-through connection between the APC module and the PC. The red lines represent the hard-wired bus traces on the Arduino board, while the blue lines represent loose cables. The APC module needs to be wired to the PC INPUT/OUTPUT lines with a crossover layout. This way, when the PC sends out data through the OUTPUT line, the APC receives it on its RX pin and then relays it to the antenna. Conversely, when the antenna receives some date the APC sends it back to the PC through the INPUT line. Because the PC is already hard-wired to the Arduino microcontroller with a crossover layout, the APC needs to be wired straight-through to the on-board connectors. The APC thus bypasses the microcontroller and plugs directly into the PC bus lines. It is unlikely that your Arduino board has any connectors with a straight-through layout. For example, the APC 220 connector on the Romeo is a crossover. Make sure to check the user manual and, when in doubt, avoid using any on-board connectors and wire up the pins by hand instead.

3.2 The remote unit


Attach the remote unit to an external power source, such as a 9 V battery.

Figure 11: Setup with the remote Arduino unit powered up by a 9 V battery. Alternatively, if you are using an Arduino to bridge the PC and the transmitter, you have the option to connect the 5 V and GND lines lines of the two boards. Although you will not be able to move your receiver any farther away than the length of the cables, this setup can still be useful for static testing or if your battery suddenly dies.

Figure 12: Setup where the power lines on the two Arduinos are connected. The 5 V line is marked in red, the GND one in blue. To connect the APC receiver to the remote Arduino, use a crossover layout. If your Arduino board has a connector labeled APC 220, you may use it. Finally, wire up the LEDs and resistances to two of the digital pins on the Arduino board (in this example, pins 02 and 03). Each LED is wired so that it turns on when the pin voltage is set to HIGH (see the Arduino programmer's API) and switches off when the voltage drops to LOW.

Figure 13: Wiring schematic for the remote unit.

4. The software
You will need to build and install two separate programs, one on the PC and one on the remote Arduino. The program that runs on the PC is a Java application which controls the APC transmitter, processes the user's commands and sends them out to the remote unit. The program running on the Arduino is written in C and it controls the APC receiver and the two LEDs. You can get the source code for the two programs from the "Downloads" section.

How to build the PC program The code for the Java application is packaged as an Eclipse project and it contains an Ant build file named build.xml. The application uses the RXTX library, which you will have to to download separately from here. (I tested the program with version 2.1-7r2). This library provides an implementation of serial and parallel port communications for the Java Development Toolkit (JDK) and it is available under the LGPL 2.1 license. The RXTX library is composed of a main file named RXTXcomm.jar and a number of systemdependent binaries. The 2.1-7r2 pre-built package provides binaries for Linux, MacOS, Solaris and Windows (32-bit); if your system is not in this list, you will have to download the source code and build the binaries yourself. To build the project, you must first import it into Eclipse. Then, unzip the RXTX package and place its content in the libraries/rxtx folder in the project directory, as shown in the figure below.

Figure 14: The project files viewed in Eclipse. The RXTX library files have been moved into the libraries/rxtx folder within the main project directory. You can now launch the build script, by right-clicking on build.xml and and selecting "Run As" -> "Ant Build". The script compiles the source code into a file named ArduinoAPC_P1.jar and places it in a folder named dist in the project directory. The script then extracts some of the library files and also places them into dist. By default, the script extracts the Windows binaries; if you work on a different system, you must edit the build.xml file, changing the value of the rxtx_bin_dir property so that it points to the correct files. To launch the application, simply double-click on ArduinoAPC_P1.jar, and the main program window should open. If you move ArduinoAPC_P1.jar to a different folder, you also need to move all the extracted files along with it, or the application will fail to launch. How to build the Arduino program The Arduino program contains one single source file, or sketch, as it is called in the Arduino jargon. To build and upload it to the board, you need to install the Arduino IDE. Once you have done this, simply connect the board to the PC, build the program by clicking on the "Verify" button and upload it by clicking on "Upload". Have a look at Appendix A for more details.

4.1 The PC program


The PC program is a Java GUI application which controls the APC transmitter and enables the user to send instructions to the remote unit. The user can send two types of commands: FORWARD and REVERSE. FORWARD turns on the green LED, while REVERSE turns on the red one. These commands are bound to two separate keyboard keys; when the application detects either of these being pressed, it sends the corresponding command to the remote unit. The key bindings can be changed on the application's main window. The program connects to the APC transmitter through the serial port. The GUI The application displays one window, which is rendered by the MainWindow class. The code uses the Java swing library to draw all the graphical elements (labels, text boxes, buttons etc.) and initializes them in the create() method.

Figure 15: The application window. At the top of the window there are two text boxes through which the user can bind the FORWARD and REVERSE keys. When the user enters some text in either box, the program extracts the first character, binds it to the corresponding instruction and discards the rest. The program also discard changes to the key bindings if the two commands are bound to the same key.
/* Code for binding the forward key */ // gui/MainWindow.java
public class MainWindow implements MotorModelObserver, SerialPortStateObserver { ... public void create() { ... _forwardKeyTextField.getDocument().addDocumentListener(new DocumentListener() { @Override public void removeUpdate(DocumentEvent e) { _motorController.bindForwardKey(_forwardKeyTextField.getText()); } @Override public void insertUpdate(DocumentEvent e) { _motorController.bindForwardKey(_forwardKeyTextField.getText()); } @Override public void changedUpdate(DocumentEvent e) {} }); ... } ... }

// motor/MotorController.java
public class MotorController implements MotorControllerInterface { ... @Override public void bindForwardKey(String keyString) { if (keyString != null && keyString.length() > 0) { Character key = keyString.charAt(0); if (key != _reverseKey) { _forwardKey = key;

} } } ... }

Below the text boxes there is a label which reports the current state of the system: either the green LED is lit (the label reads FORWARD), or the red one is (REVERSE) or neither is (REST). Next, there is another label which indicates the ID of the serial (COM) port that the application is currently connected to. At start-up, the program opens the first available port, usually COM1. This may or may not be the actual port that is being used by the APC transmitter; the program has no way to tell. If the transmitter is connected to a different port, the program will be unable to send out commands. To fix this, there is is a button at the bottom of the window which enables the user to cycle through all the available COM ports until finding the correct one. You simply have set up the remote unit and the APC transmitter, then launch the application and go through all the ports until you find one where the remote unit responds to commands. Alternatively, on Windows you can get the ID of the transmitter's COM port from the Device Manager, under "Ports (COM & LPT)".

Figure 16: Screenshot of Windows the Device Manager. The transmitter is using COM2 (see the USB-to-UART label), so you will need to cycle the application until it connects to this port. The instruction-processing loop This section looks at how the program processes user instructions and keeps track of the state of the remote unit. On the GUI side, a KeyListener object bound to the main window captures every key pressed by the user and notifies it to a MotorController object.
// gui/MainWindow.java
public class MainWindow implements MotorModelObserver, SerialPortStateObserver { ... public void create() { ... _mainWindow.addKeyListener(new KeyListener() { @Override public void keyPressed(KeyEvent e) { _motorController.processPressedKey(e.getKeyChar()); } @Override public void keyReleased(KeyEvent e) { _motorController.processReleasedKey(e.getKeyChar()); } @Override public void keyTyped(KeyEvent e) {} }); ... } ... }

The controller filters the keys, retains those that are mapped to FORWARD or REVERSE and sends the corresponding commands to a MotorModel object. To keep consistent with the motor analogy, the controller class can issue four possible commands: start or stop the motor rotation, in either direction. Starting a forward rotation results in the green LED lighting up; a reverse rotation lights up the red one, and a full stop from either direction turns off both LEDs.
// motor/MotorController.java
public class MotorController implements MotorControllerInterface { private Character _forwardKey = 'z'; private Character _reverseKey = 's'; ... @Override public void processPressedKey(Character inputKey) { if (inputKey.equals(_forwardKey)) { _model.rotateForward(); return; } if (inputKey.equals(_reverseKey)) { _model.rotateReverse(); } } @Override public void processReleasedKey(Character inputKey) { if (inputKey.equals(_forwardKey)) { _model.stopRotatingForward(); } if (inputKey.equals(_reverseKey)) { _model.stopRotatingReverse(); } } }

The MotorModel class is responsible for filtering out redundant and conflicting instructions and for transmitting the remaining ones to the remote unit. An example of a redundant instruction would be the program sending the FORWARD command while the green LED is already lit. An example of conflicting instruction would be the user pressing the FORWARD key, then pressing the REVERSE key while keeping FORWARD down. When the user is issuing two conflicting commands at once, the program has to determine which one to send to the transmitter and which one to ignore. In the previous use case, for example, because the user pressed REVERSE after FORWARD, the program determines that the system is no longer in the FORWARD state and has switched to REVERSE. It therefore ignores the FORWARD command and accepts the REVERSE one. To determine which commands are redundant or conflicting, MotorModel needs to keep track of the state of the system, which it does by implementing a state machine. This is a programming construct that has many applications in automated systems, from robotics to game AI programs. The base idea behind a state machine is that a system can be modeled as a series of finite states, and that certain events can trigger a transition between any two of these. Take for instance a game AI program: at any given moment, it may be either scanning the environment, or attacking the player, or running away. The system transitions from one state to another in response to specific events: for instance, the AI may switch from scanning mode to attacking mode after detecting the player. While

some events may trigger a transition, some others (for example, the AI detecting an ally) may not. In this program, the MotorModel class defines three possible states for the system: FORWARD, REVERSE and REST. Each state is defined by a Java class (respectively, ForwardRotationState, ReverseRotationState and RestState) that implements the MotorRotationState interface. Instances of these classes are stored as three internal attributes of the MotorModel class; an additional attribute named _currentState stores the current state of the system. The MotorRotationState interface defines four methods, one for each instruction that the controller can send to the model. Each implementation overrides these methods so that they trigger a change in state if needed. For example, if the system is in the FORWARD state, the REVERSE instruction changes it to REVERSE:
// motor/ForwardRotationState.java
public class ForwardRotationState implements MotorRotationState { ... @Override public void rotateReverse() { // Immediately switch to the opposite direction _model.changeState(_model.getReverseState()); } ... }

If an instruction is, say, redundant and should have no effect on the system in its current state, the corresponding override is left void. This is the case, for instance, when the system is in the FORWARD state and a FORWARD instruction is issued:
// motor/ForwardRotationState.java
public class ForwardRotationState implements MotorRotationState { ... @Override public void rotateForward() { // Do nothing - just keep rotating in the same direction } ... }

When the state of the system changes, MotorModel notifies a SerialPortController object, which in turn relays the instruction to the RF transmitter:
// motor/MotorModel.java
public class MotorModel implements MotorModelInterface { ... private void notifyObserversOfChangeInState() { for (MotorModelObserver observer : _observers) { observer.motorStateChanged(); } } ... public void changeState(MotorRotationState newState) { _currentState = newState; notifyObserversOfChangeInState();

} ... }

// serialPort/SerialPortController.java
public class SerialPortController implements MotorModelObserver, SerialPortControllerInterface { ... private final byte _serialPortForward = (byte)'0'; private final byte _serialPortReverse = (byte)'1'; private final byte _serialPortRest = (byte)'2'; ... @Override public void motorStateChanged() { MotorStateCode stateCode = _model.getMotorStateCode(); byte command; switch (stateCode) { case FORWARD: command = _serialPortForward; break; case REVERSE: command = _serialPortReverse; break; default: command = _serialPortRest; } System.out.println("Transmitting command: " + command); _serialPort.writeToSerial(command); } }

MotorModel also notifies the GUI, which in turn updates the display.
// gui/MainWindow.java
public class MainWindow implements MotorModelObserver, SerialPortStateObserver { ... @Override public void motorStateChanged() { MotorStateCode spinState = _motorModel.getMotorStateCode(); switch (spinState) { case FORWARD: _motorStatusLabel.setText("Motor state: FORWARD"); break; case REVERSE: _motorStatusLabel.setText("Motor state: REVERSE"); break; default: _motorStatusLabel.setText("Motor state: REST"); } } }

The serial port connection handler The SerialPortModel class takes care of initializing the connection to the APC transmitter through the serial port. When this class is instantiated, its constructor retrieves the list of available ports and opens the first one. It also intializes the port parameters, setting the speed to 9600 baud and the parity check to even.
// serialPort/SerialPortModel.java
public class SerialPortDriver implements SerialPortDriverInterface { private private private private ... static SerialPortDriver _serialPortDriver; SerialPort _port = null; OutputStream _serialOutput = null; String _portName = null;

private void closeCurrentPort() { if (_port != null) { try { _port.close(); } catch (Exception e) { System.out.println("ERROR: Unable to close the serial port."); System.out.println(e.getMessage()); e.printStackTrace(); } } _port = null; _serialOutput = null; _portName = null; }

private Enumeration<CommPortIdentifier> getSerialPorts() { List<CommPortIdentifier> list = new ArrayList<CommPortIdentifier>(); Enumeration ports = CommPortIdentifier.getPortIdentifiers(); while (ports.hasMoreElements()) { CommPortIdentifier port = (CommPortIdentifier) ports.nextElement(); if (port.getPortType() == CommPortIdentifier.PORT_SERIAL && ! port.isCurrentlyOwned()) { list.add(port); } } return Collections.enumeration(list); } private void cycle() { try { ... ... while (ports.hasMoreElements()) { CommPortIdentifier port = ports.nextElement(); try { _port = (SerialPort) port.open("Serial port", 5000); } catch (Exception e) { System.out.println("ERROR: Unable to open port " + port.getName() + ". Trying the next one."); Enumeration<CommPortIdentifier> ports = getSerialPorts();

System.out.println(e.getMessage()); e.printStackTrace(); closeCurrentPort(); continue; } _port.setSerialPortParams(9600, 8, SerialPort.STOPBITS_2, SerialPort.PARITY_EVEN); _portName = port.getName(); _serialOutput = _port.getOutputStream(); break; } ... } catch (Exception e) { System.out.println("ERROR: Unable to recycle port."); System.out.println(e.getMessage()); e.printStackTrace(); closeCurrentPort(); } } ... }

The SerialPort and the CommPortIdentifier classes are part of the RXTX library. Data is transmitted through the serial port by writing to its attached OutputStream object and then flushing it. If an exception is caught upon writing to the port, this is cycled.
// serialPort/SerialPortModel.java
public class SerialPortDriver implements SerialPortDriverInterface { ... @Override public void writeToSerial(byte key) { try { if (_serialOutput != null) { _serialOutput.write(key); _serialOutput.flush(); } } catch (Exception e) { System.out.println("ERROR: Unable to write to port."); System.out.println(e.getMessage()); e.printStackTrace(); cycle(); } notifyObservers(); } ... }

The user can independently cycle the port by clicking on the button in the GUI. Whenever the port changes, SerialPortDriver notifies MainWindow, which updates the display.
// serialPort/SerialPortModel.java

public class SerialPortDriver implements SerialPortDriverInterface { ... @Override public void cyclePort() { cycle(); notifyObservers(); } ... public void notifyObservers() { for (SerialPortStateObserver observer : _observers) { observer.portStatusChanged(); } } }

// gui/MainWindow.java
public class MainWindow implements MotorModelObserver, SerialPortStateObserver { ... @Override public void portStatusChanged() { _serialPortLabel.setText("Port currently in use: " + _portDriver.getPortName()); } }

4.2 The Arduino program


The Arduino program contains two functions, named setup() and loop(), as required by the Arduino API. The setup() method is executed only once, at start up. It contains the code that initializes the hardware and any global variables. The loop() method runs continually as long as the platform is on. It contains the main program code, such as all input/output operations. When programming an Arduino, you should strive to keep the loop() method as short and simple as possible, so as to reduce its execution time to a minimum. If this function takes too long to run, the platform is unable to handle incoming instructions in real time. In this example, the Arduino code is very short, as most of the processing is done on the PC side. The header contains the definition of a few constants, namely the pin numbers to which the LEDs are connected (02 and 03) and the instruction key mappings. The character '0' is mapped to the green LED on pin 02, the character '1' to the red LED on pin 03. Any other key turns off both LEDs.
// LEDs.pde enum activeStates { FORWARD = 0, REVERSE, }; const int pins[] = {2, 3}; const int numPins = 2; const char commandKeyBindings[] = {'0', '1'};

The setup() method initializes the serial port to a rate of 9600 baud (the same value as on the PC side). It then sets pins 02 and 03 to OUTPUT mode. Pins that are so configured have a low output impedance and can thus supply a high current.
// LEDs.pde void setup() { Serial.begin(9600); for (int i=0; i<numPins; i++) { pinMode(pins[i], OUTPUT); } }

The loop() method calls the read() API function, which reads out the serial port byte-by-byte. If an extracted byte matches either '0' or '1', the program turns on the corresponding LED: first, it turns both LEDs off by setting their pins to LOW (0 V); then, it lights up the designated LED by setting its pin to HIGH (5 V). If the readout fails and returns -1 because there are no incoming instructions, nothing happens.
// LEDs.pde void loop() { char val = Serial.read(); if (-1 != val) { digitalWrite(pins[FORWARD], LOW); digitalWrite(pins[REVERSE], LOW); if (val == commandKeyBindings[FORWARD]) { digitalWrite(pins[FORWARD], HIGH); } else if (val == commandKeyBindings[REVERSE]) { digitalWrite(pins[REVERSE], HIGH); } } }

5. Video

Object 1

6. Downloads
The PC and Arduino programs in one package

Appendix A
The Arduino is an open-souce electronics prototyping platform built around the Atmel AVR microcontroller. The base Arduino model (the Uno) is built on the ATmega328 controller; other models may use different but compatible chips from the same product family (for example, the Arduino Mega uses the ATmega2560). The base Arduino board provides a number of input/output pins, both analog and digital, and can be connected to a PC through USB. Larger models may provide redundant pins and additional connectors for specific devices. to program the Arduino, you first have to download the IDE on the project website. This IDE, which supports multiple operating systems, provides an Arduino-specific API, a compiler, an editor and a utility to upload programs to the board. Arduino programs, or sketches as they are also called, are written in C++ and use the .pde extension. The Arduino API provides methods to control the input/output connectors, to set the voltage of the analog and digital pins, and to read and write data to the serial bus. The Arduino user community has created a number of additional libraries that expand on these base functions. When you choose to integrate a new library into your sketches, you should first make sure that your platform has enough processing power to handle it without degrading performance. In general, a sketch should be able to run on any Arduino model. Arduinos can operate with many peripherals, including motors, servos, LCD screens and other electrical circuits. Most platforms can be expanded through shields. These are adapters with connectors designed for specific peripherals that can be stacked on top of an Arduino board. For instance, the V5 I/O expansion module from DFRobot can be used to plug in RF modules like the XBee or the APC 220. Some shields contain additional circuitry, such as H-bridges, which are for

controlling DC and stepper motors. Some Arduino clones, like the Romeo in this tutorial, integrate these extra components directly on the main board. Setting up the IDE and running a test program Download the IDE from the project website, then install and run it on your PC. When launched, it will display a blank sketch, as shown in Figure 17. In order to run a sketch, you must first build and upload it to the board. You can perform both tasks within the IDE.

Figure 17: Main window of the Arduino IDE, displaying a blank sketch. The IDE includes a list of sample programs (accessible through the menu "Files" -> "Examples") that demo the Arduino API. When you are unsure about how to use an API function, it can be very useful to browse this list for practical examples. All these programs are also documented thoroughly on the Arduino website. Here, we will compile the sketch called "Blink" ("1.Basics" -> "Blink"), which is the "Hello World!" of Arduino programming. This program sets the digital pin 13 on the Arduino board to alternating HIGH and LOW voltages (5 V and GND respectively) every second. To see the effect of the changing voltage, you must connect an LED and a resistance in series between pin 13 and GND on a breadboard (this is not necessary on many Arduino models, as pin 13 is already connected to an on-board LED). When you run the program, the LED will start blinking. Compile the sketch by clicking on the "Verify" button. If the compilation fails, the screen will display all error messages on the console at the bottom. Once compilation succeeds, connect the Arduino to the PC with an USB cable and upload the program by clicking on the "Upload" button. The compiled code will be written on the EEPROM memory on the AVR controller, which will start running it automatically. The IDE also provides a tool to monitor all data exchanges between the PC and the Arduino, which you can access by clicking on the "Serial Monitor" icon.

Figure 18: The "Verify", "Upload" and "Serial Monitor" buttons on the main screen of the IDE. More documentation on the Arduino The Arduino project's main site. List of Arduino compatible shields. More tutorials: luckylarry.co.uk/arduino-projects/ tronixstuff.wordpress.com/tutorials/ arduinotutorials.com/ jeremyblum.com/category/arduino-tutorials/

Appendix B
The APC 220 is an RF module made by Appcon Technologies that operates in the 418-455 MHz band. According to the datasheet, it has a maximum range of 1000 m (unobstructed) at a rate of 2400 baud. APC modules can be connected to both PCs and Arduinos and can work as receivers and

transmitters at the same time. Before you start using a pair of APCs, you must check two things: that they use the same configuration (transmission rate, frequency etc.) and that they operate within the radio communications regulations in your country. For example, in the European Union the broadcast frequency should be set at 433 MHz with power not exceeding 10 mW. To configure the device, you will need to connect it to a PC using a USB-to-UART adapter similar to the ones shown in Figure 19. You may usually purchase adapters from the same retailers that sell APC 220s. Some retailers even bundle an adapter with each pair of twin modules. While some adapters have a connector that fits the pin layout on an APC, some others may require to wire up each pin separately. Of the seven pins on an APC, only four need to be connected: 5 V, GND, RX and TX.

Figure 19: A pair of USB-to-UART adapters. The one on the left has a socket designed for the APC. The one on the right needs to be wired pin-by-pin. Every USB-to-UART adapter contains a chip that bridges the USB bus on the PC side to the asynchronous UART serial bus of the APC. To use the adapter, you will first need to retrieve the drivers for its chip and install them on the PC. On my setup, for example, the chip is a CP2102 model from Silicon Labs (see Figure 20). As far as I can tell, this is a common model. If the chip on your adapter is from the same manufacturer and product family, you may download its drivers here. Otherwise, you will have to identify the manufacturer and search through their website. To do this, simply do a Google search on the part reference printed on the chip, which will take you straight to the product datasheet.

Figure 20: Closeup of the CP2102 chip on the USB-to-TTL adapter shown in Figure 3. A Google search for part reference "CP2102" takes to the device driver download page. After installing the drivers, connect the APC to the adapter and plug it into a USB port on the PC. You should now be able to see the adapter displayed as a COM port in the device manager.

Figure 21: Once the drivers are successfully installed and the APC is connected through its adapter, you should be able to view it as a COM port in the device manager. You then need to run a program called RF-Magic, which connects to the APC module and allows to rewrite its internal configuration. Start RF-Magic with the APC plugged in, running it as an administrator if your operating system is Windows Vista or 7. The program should detect the adapter's COM port automatically and display it in a combo box labeled "PC series" in its main screen.

Figure 22: The main window of the RF-Magic application. The combo box label "PC series" indicates that the program has detected an APC adapter on COM3, which is the same port reported by the System manager in Figure 21. The main screen of RF-Magic is organized as follows. A panel named "RF parameters" lists all the radio communication settings, including the operating frequency and the baud (RF TRx) rate. You must set the same values on the two modules (in my case, the frequency is set at 433 MHz, the transmission rate at 9600 baud and the power to minimum). In addition, the value for the TX rate should match those that are hard-coded in the programs that run on the PC and the Arduino (cf. Section 3.1 and 3.2).

Just below the first panel, a second one named "Series parameters" displays the serial bus settings. Once again, the values for the rate and parity must match those hard-coded in the PC program (in this example, 9600 baud and even parity). At the bottom of the window, the "Write" button saves the new settings to the APC, while the "Read" button reads the current settings from the module and displays them on screen. Finally, RF-Magic displays the "Found device!" message in the status bar when it successfully connects to an APC. Unfortunately, RF-Magic will sometimes fail to locate a device, as documented here and here. I tested this program on two computers: on one, it worked flawlessly, while on the other it seemed to detect the device at first (it was able to display its COM port) but then could neither read nor write to it. Eventually, I had to shut down RF-Magic, manually change the port identifier, then restart the program. At this point, the "PC Series" combo box in the main screen listed two COM ports: the original identifier and the new one. By selecting the original identifier, I was finally able to have RF-Magic detect the device. Selecting the new identifier returned once again an error. This may of course have been a configuration issue on my side, rather than a fault of RF-Magic, but I have mentioned it anyway should you encounter a similar problem. To manually change a COM port identifier, right-click on the port in the Device Manager, then select "Properties". This opens a second window where you must click on the the "Port Settings" tab, followed by the "Advanced" button. This opens a third window with a combo box at the bottom where you can select a new identifier. The procedure is shown in the figure below.

Figure 23: Procedure to change a COM port identifier from the device manager. Relevant links The APC 220 datasheet. The APC 220 user manual. The program RF-Magic. The driver download page for the CP210X product family from Silicon Labs The datasheet for chip CP2102. Two forum posts discussing how to set up APC modules

Vous aimerez peut-être aussi