











































Studirajte zahvaljujući brojnim resursima koji su dostupni na Docsity-u
Zaradite bodove pomažući drugim studentima ili ih kupite uz Premium plan
Pripremite ispite
Studirajte zahvaljujući brojnim resursima koji su dostupni na Docsity-u
Nabavite poene za preuzimanje
Zaradite bodove pomažući drugim studentima ili ih kupite uz Premium plan
Kurs za arduino za pocetnike
Tipologija: Vodiči, Projekti, Istraživanja
1 / 51
Ova stranica nije vidljiva u pregledu
Ne propustite važne delove!












































The first Arduino was developed over ten years ago by the Interaction Design Institute of Ivrea, based near the Italian city of Turin. The original aim of the project was to provide students with a simple yet powerful platform on which to develop interactive systems. Since then, the Arduino’s hardware and software have evolved on a continuous basis, but the idea behind the Arduino has essentially remained the same. Today, the Arduino has become a highly effective platform for anyone needing a low-cost microcontroller suitable for use in a very wide range of applications. With only a few exceptions, members of the Arduino family (together with a multitude of clones and compatible microcontroller boards) are all based on the popular range of chips developed and manufactured by Atmel. The ATmega is the most commonly used device, a powerful 8-bit general purpose RISC- based CMOS microcontroller with 32 Kbytes of built-in flash memory. Members of the Arduino family include the Uno, Leonardo, Due and Micro models. In addition, there’s a wide variety of low-cost clones and compatibles that emulate the features of each of their original Arduino counterparts. Currently, Uno clones can be obtained from Chinese
suppliers at a cost of a little over £3 with free postage – good news for anyone working on a tight budget. At this point it’s important to note that genuine Uno boards are invariably marked with the official Arduino logo. Low- cost clones can work well and provide you with a system that is extremely cost-effective, but in more critical applications there’s a need to ensure the highest level of software and hardware compatibility and it can be well worth investing in an original and genuine version. We will explore this in greater detail in a future part of Teach In 2016.
The Arduino Uno The entry-level Uno contains virtually everything that you need to implement a complete microcontroller system. The only additional items are a power source and a standard A-to-B USB cable for programming. The Uno will operate quite happily from nothing more than
a standard 9V PP3 battery, making the microcontroller ideal for use in stand- alone applications where there’s no mains supply available. Alternatively, the Uno can derive its power from an external DC supply of nominally 9V or via a USB cable and a powered USB port. The Uno board measures approximately 69mm by 53mm and provides a total of 14 digital input/output lines, together with six analogue inputs. To compensate for the lack of conventional direct analogue output lines, signals on six of the 14 digital I/O lines can, where necessary, make use of pulse- width modulation (PWM) to generate up to six analogue outputs. Later in the series we will explain how this works, but for now you only need to be aware that, with appropriate circuitry, the Uno can produce analogue outputs as well as make use of regular analogue inputs. Fig.1.2 shows the Uno’s board layout with the main components and connectors identified. The Arduino Uno technical specifications are shown in Table 1.1.
What will I need? To get the best out of our series you will, of course, need access to an Arduino. We recommend that you get started with the immensely popular Arduino Uno. You can get hold of one of these at very modest cost from a variety of sources (see Introducing the Arduino ). You will also need a laptop or desktop computer with either Windows or Linux on which to develop your code. Your computer will need to have a spare USB
port and you will also need a standard USB A-to-B cable.
This month In this month’s Teach-In 2016 , we will take a first look at the Arduino, explaining why it has become so popular. Arduino Workshop deals with installing and running the Arduino’s simple but powerful integrated development environment (IDE), while Coding Quickstart introduces the different types
of data that you will encounter in an Arduino environment. Get Real deals with interfacing switches and LEDs to the Arduino’s digital I/O ports and provides some simple example ‘sketches’ to get you started with C coding. Finally, Arduino World introduces the flexible and easy- to-use Arduino Simulator developed by Stan Simmons at Queen’s University ECE. This brilliant free software will allow you to experiment with a virtual Arduino Uno
Introducing the Arduino______________________
Fig.1.2. Uno board layout showing main components, power and I/O connectors
Microcontroller ATmega328P
**Clock speed 16MHz Flash memory 32KB ***
Static RAM (SRAM) 2KB EEPROM 1KB
Supply voltage 5V
Recommended DC input voltage range 7V to 12V * Digital I/O pins 14
Digital I/O pins available for PWM output 6 * Analogue input pins 6
Max. DC current output per pin 20mA Max. DC current available from 3.3V supply 50mA
Dimensions 68.6 × 53.4mm
Weight 25g
Table 1.1 Technical specifications for the Arduino Uno (* Notes: 1. 512 bytes are used for the bootloader,
2. Maximum DC input voltage is 20V, 3. See text)
several different functions depending on the chip’s software configuration.
Port-B (PB0 to PB7) Port-B is an 8-bit bi-directional I/O port with internal pull-up resistors (which can be individually selected for each bit). The Port-B output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port-B pins that are externally pulled low will source current if the pull-up resistors are activated. The Port-B pins are placed in a tri-state (high-impedance) condition when a reset condition becomes active, even if the clock is not running. Depending on the clock selection fuse settings, PB6 can be used as input to the inverting oscillator amplifier and input to the internal clock operating circuit. In the same manner, PB7 can be used as output from the inverting oscillator amplifier. If the internal calibrated RC oscillator is used as chip clock source, PB6 and PB7 (pins 9 and 10 of the DIL package version of the ATmega328) are used as inputs the asynchronous Timer/Counter 2.
Port-C (PC0 to PC5) Port-C is a 7-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The PC0 to PC output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port-C pins that are externally pulled low will source current if the pull-up resistors are activated. The Port-C pins are tri-stated when a reset condition becomes active, even if the clock is not running. PC (pin-1 of the DIL packaged version of the ATmega328) can be fuse programmed for use as an I/O pin or to function as a RESET pin. In the latter case, a RESET will be generated when a low level is present on this pin.
Port-D (PD0 to PD7) Port-D is an 8-bit bi-directional I/O port with internal pull-up resistors (selected for each bit). The Port-D output buffers have symmetrical drive characteristics with both high sink and source capability. As inputs, Port-D pins that are externally pulled low will source current if the pull-up resistors are activated. The Port-D pins are tri-stated when a reset condition becomes active, even if the clock is not running.
USB interface The Arduino’s Universal Serial Bus (USB) interface is external to the ATmega328. In current versions of the Uno the interface is implemented using an ATmega8U2 CMOS RISC-based 8-bit microcontroller. This replaces the popular FTDI FT232 serial interface chip found in earlier versions and in many other microcontroller designs. The Uno’s USB interface is brought out to a standard four-pin Type-A printed circuit board connector (see Fig.1.2). The ATmega328 is programmed from the USB port using its own resident
bootloader code that will let you upload your own code to it without the use of an external hardware programmer. Alternatively, you can bypass the bootloader so that you can then program the microcontroller through the Uno’s in- circuit serial programming (ICSP) header.
Power supplies The Uno can derive its power from various sources, including a powered USB port using the standard A-to-B USB cable that we mentioned earlier (see Fig.1.6). Alternatively, an external supply derived from a battery or AC- to-DC adapter can be connected to the external 2.1mm (centre-positive) DC connector. The power source is selected automatically. As a further alternative, a supply derived from a battery may be connected directly to the ground (GND) and input voltage (Vin) pins of the POWER header connector. The specifications (see Table 1.1) state that operation should be from an external DC supply of between 6V and 20V. However, to ensure reliable operation we would recommend that the range of supply voltages is kept between 7V (minimum) and 12V (maximum). This makes a small 9V battery-derived supply ideal for applications where a mains supply is unavailable. During software development it can be more convenient to supply power using the Uno’s USB connector and a hub or other powered external USB device. In this case, the supply voltage will be +5V. The USB connector can also be used just to provide power for the Uno. In most cases this will involve the use of a USB charger and matching cable. To provide power for external boards and ‘shields’, a separate 3.3V power rail is available from the Uno’s on-board voltage regulator. It’s important to note that the current available from this supply should not exceed 50mA. Having briefly described the Uno’s hardware configuration it’s now time to move on to explain how the digital and analogue I/O lines are configured and used for different applications.
Using digital I/O Each of the 14 digital pins on the Uno can be configured as an input or output by using the appropriate C functions, pinMode(), digitalWrite(), and digitalRead(). All of the digital I/O lines operate at standard TTL-compatible levels. Each of the I/O pins can source or sink a maximum current of 40mA and internal pull-up resistors of around 20 to 50kΩ can be selected where necessary. Note that the internal pull-up facility is disabled by default). It is important to be aware that many of the digital I/O lines also have specialised functions (as previously mentioned).
Serial I/O using digital I/O pins 0 and 1 These include the serial RX and TX pins that can be used to receive (RX) and transmit (TX) TTL serial data using pins 0 and 1 respectively. These pins are
connected to the corresponding pins of the ATmega8U2 serial USB-to-TTL device.
Interrupt inputs using digital I/O pins 2 and 3 These two pins are available for use with external interrupts. They can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value. The attachInterrupt() function can be used to configure the interrupt feature.
Pulse-width modulation (PWM) output using digital I/O pins 3, 5, 6, 9, 10, and 11 These six lines can be used to provide outputs that are pulse-width modulated (PWM). This feature can be used to provide quasi-analogue outputs using the analogWrite() function.
Serial SPI communication using digital I/O pins 10, 11, 12 and 13 These four pins support SPI serial communication by providing SS, MOSI, MISO and SCK signals respectively. Note that although the underlying hardware supports this interface, SPI communication is not currently included in the Arduino language.
LED indication using digital I/O pin 13 An LED status indicator is provided for this (and only this) I/O pin. When the pin is high, the LED will be on, and when low, the LED will be off. The built-in LED provides a handy way of testing simple I/O code routines without the need to connect an external indicator.
Using analogue I/O In addition to the 14 digital I/O lines, the Uno has six analogue inputs, each of which provide 10 bits of resolution (1024 different values). By default, they measure from ground to 5V, though it is possible to change the upper end of the measurement range using the AREF pin and the analogReference() function (more of this in a future instalment). As with the digital I/O lines, some of the analogue input pins also have specialised functions.
I^2 C communication using analogue pins 27 and 28 Analogue I/O port lines 4 and 5 (pins 27 and 28 respectively) can be used to provide access to the SDA and SCL signals respectively used to facilitate the two-wire interface (TWI or I 2 C).
Fig.1.6. USB Type-A-to-Type-B connector
Analogue output (as distinct from input) can be obtained from six of the digital I/O lines (pins 5, 11, 12, 15, 16 and 17). In a future instalment we will explain how this works, but for now, you just need to know that by switching the digital outputs on and off and averaging the voltage produced it is possible to produce an analogue voltage. For example, if one of the digital outputs is alternately taken high (+5V) for 50% of the time and low (0V) for 50% of the time then the average voltage produced will be +2.5V.
Communicating with the Uno The Arduino Uno has a number of facilities for communicating with a computer, another Arduino, or other microcontrollers. The ATmega provides UART TTL (5V) serial communication, which is available on digital pins 0 (RX) and 1 (TX). An ATmega8U2 (see earlier) provides serial communication over USB and appears as a virtual COM port when used with software running on an external Windows or Linux-based computer. The ATmega8U2 firmware uses the standard USB COM drivers, and no external driver is needed. However, when using some versions of Windows, clones and compatibles, a driver information (.INF) file maybe required (see later). The Arduino’s integrated development environment (IDE) incorporates a serial monitor which allows simple text data to be sent to and from the Arduino board. The RX and TX LEDs on the board will flash when data is being transmitted via the USB-to-serial chip and USB connection to the computer (but not for TTL serial communication using pins 0 and 1). A software serial library allows for serial communication on any of the Uno’s digital pins. As already noted, the Uno can also support I 2 C (TWI) and SPI communication. This is ideal for communication with external hardware devices, sensors and transducers. The Arduino Uno has a resettable polysilicon fuse that’s designed to protect against short-circuit and overcurrent conditions. If more than 500mA is applied to the USB port, the fuse will automatically break the connection until the short or overload is removed. Although computers usually have their own internal protection, this fuse does provide you with an extra layer of protection.
do this is usually supplied with the microcontroller in question.
We’ve installed the IDE package successfully on a whole host of different computers, including some running 32- and 64-bit versions of Windows 7, 8 and 10 and also a couple running different flavours of Linux. The step-by- step procedure described here was carried out on a computer running Windows 7, but the process is similar, if not quite identical, on o t h e r m a c h i n e s. N o t e that an installation under Linux may require the installation of the Java run- time environment (JRE) if not already installed. Also, if you are using a low-cost Arduino clone (ie, not a ‘genuine’ Arduino) you might need a different USB driver from the one supplied with the official IDE package.
Arduino Workshop: Installing
and configuring the IDE ______________________
Before you can begin to enter code into your Arduino you will need to connect it to a PC that has a copy of the Arduino’s IDE installed on it. The process is quite painless, but does require a machine with an Internet connection so that you can download the latest version of the IDE package.
Fig.1.7. Selecting installation options
Fig.1.8. Choosing a destination folder for the installation
The Arduino Uno uses the standard USB CDC drivers that are normally provided by the operating system. These drivers allow the host computer to communicate with the ATmega8U2 on the Arduino board. Some other Arduino boards use FTDI drivers to communicate with an FTDI chip on the board (or in the USB- serial convertor). The easiest way to check if the drivers for your board are installed correctly is by clicking on Tools and then Port from the drop-down menu (see Fig.1.14). On Windows 7 (particularly the 64-bit version), you might need to go into the Device Manager and update the drivers for the Uno. Just right click on the device (the board should be connected to your computer), and point Windows at the appropriate driver information (.INF) file. You will find this located in the Drivers directory of the Arduino software (not in the FTDI USB Drivers sub-directory). Further information concerning a failed driver installation is available from the official Arduino website. Finally, it’s important to remember that you will be unable to communicate with the Arduino if there’s no bootloader present. It’s easy to check this by simply resetting the board (by removing the power or pressing the reset button) and noting the state of the L-LED (connected to digital I/O pin-13). If the bootloader
is present this LED should start to blink. If the LED doesn’t blink, it’s likely that the bootloader is missing. We will explain how a missing bootloader can be reinstated in a future instalment of Teach-In 2016.
1 standard red LED 2 470Ω resistors (R1 and R3) 1 4.7kΩ resistor (R2) Miniature push-button switch Miniature loudspeaker of between 8Ω and 40Ω impedance
Circuit The circuit of our LED and switch interface is shown in Fig.1.15. The LED (D1) is connected to the Arduino’s Digital I/O pin-13, which will be configured as an output. The push-button switch (S1) will be connected to Digital I/O pin- configured as an input. R1 is connected in series with D1 to limit the LED current, while R2 is used to pull-up the input voltage to a HIGH (+3.3V) level when S1 is not being operated.
Fig.1.14. Error message resulting from incorrect port setting
Fig.1.15. Circuit of the LED and switch interface
Fig.1.16. Fritzing breadboard arrangement for Fig.1.
Fig.1.17. Actual breadboard arrangement
Get Real : Your first
Arduino sketch ______________________
In our first Get Real it’s time for you to explore some of your new Arduino’s capabilities and try out your first Arduino program, or ‘sketch’. To keep things simple we’ve minimised the need for anything much in the way of additional hardware, so you will only need a mini-breadboard and a few commonly available components. The aim of this exercise is simply to control an LED from a switch, but if you are already familiar with this task feel free to jump forward to Coding Quickstart or Arduino World.
You will need Arduino Uno with power supply USB A-to-B cable Computer with an available powered USB port Mini-breadboard with a selection of coloured connecting leads (^) Fig.1.18. LED connections
Breadboard layout The components are shown mounted on the mini-breadboard in Fig.1.16. The LED will need to be connected with the correct polarity so that its cathode (the shorter of the two leads) is connected to 0V, as shown in Fig.1.18.
Code Listing 1 shows the code sketch for the LED and switch application (you might
to make the code more readable. In a future Teach-In 2016 we will explain this in more detail. Before you start to enter your code click on File and New to produce a new editing window with a blank code template. You will find that the IDE has already started you off by adding empty setup() and loop() functions. You can now type in your code as shown above. When you finish, don’t forget to save your work by clicking on ‘File’ and ‘Save’ or ‘Save As…’. Next, click on ‘Sketch’ and ‘Verify/Compile’. When you’ve corrected any coding errors that the compiler reports you will be ready to upload your code to the Uno. Just click on the upload arrow and watch the progress report. The LEDs on the Uno should flash and the code should begin to execute. At this point, D should become illuminated (along with the L-LED on the Uno board) whenever the push-button is pressed.
Toggle action In many cases it might be desirable to ‘toggle’ the state of an output line rather than simply turn it on when the push-button is pressed and off when it is released. With the toggle action the LED will become illuminated when the button is first pressed and it will remain illuminated until the button is pressed again (after which it will remain turned turn off). In other words, every time the button is pressed the state of the LED will change. In order to accomplish the toggle action the Uno will need to ‘remember’ the state of the line so it can recognise when it has been changed. The Code sketch in Listing 2 shows how this can be done.
Adding some sound Now let’s add some sound to our application so that an audible warning will be generated whenever the button is being pressed. We will need to add a miniature loudspeaker to the circuit and breadboard layout, as shown in Fig.1.19 and 1.20. The loudspeaker (LS1) is connected to Digital I/O pin-
Listing 2
/* Simple LED and button example. Uses an external button connected to pin-12 to toggle the state of an LED connected to pin- */
int inButton = 12; // Switch connected to digital pin- int outLED = 13; // LED connected to digital pin-
boolean LEDstate = LOW; boolean buttonState = HIGH; boolean lastButtonState = LOW;
void setup() { pinMode(inButton, INPUT); // Button is an input pinMode(outLED, OUTPUT); // LED is an output }
void loop() { buttonState = digitalRead(inButton); if (buttonState == LOW && lastButtonState == HIGH) { if (LEDstate == LOW){ LEDstate = HIGH; } else { LEDstate = LOW; } } digitalWrite(outLED, LEDstate); lastButtonState = buttonState; }
Listing 1 /* Simple LED and button example. Uses an external button connected to pin-12 to control an LED connected to pin- */
int inButton = 12; // Switch connected to digital pin- int outLED = 13; // LED connected to digital pin-
boolean LEDstate = LOW;
void setup() { pinMode(inButton, INPUT); // Button is an input pinMode(outLED, OUTPUT); // LED is an output }
void loop() { if (digitalRead(inButton) == LOW) // button has been pressed so turn the LED ‘on’ { LEDstate = HIGH; digitalWrite(outLED, LEDstate); } else // button has been released so turn the LED ‘off’ { LEDstate = LOW; digitalWrite(outLED, LEDstate); } }
not understand what all of the code does, but things will become clearer as we progress through the series): The code must be entered into the IDE and then saved before compiling and uploading it to the Arduino as described earlier in Arduino Workshop. Note how we’ve added comments to the code in order to explain what’s going on. Notice also how we’ve indented the lines and added spacing in order
This line of code defines and initialises a variable that we’ve named powerLED. We’ve told the Arduino that it is to be handled as an int (ie, an integer) and that it is to be given an initial value of 11. The statement ends with a semicolon (;) and this is followed by a brief comment designed to act as a reminder of what the purpose of the statement is. Brief comments like this can be invaluable later on when the time comes to do some software maintenance and also when code is shared among several authors. Later on in the program code you might find a line of the following form:
digitalWrite(powerLED, HIGH); // Illuminate the // power good LED
Even if you’ve never done any coding before you can probably make a reasonable guess of what this statement does. At another point in the code you might find something like this:
if(powerGood = = FALSE) { digitalWrite(powerLED, LOW); }
The above code fragment turns the ‘power good’ LED off when the system has sensed a problem with the power supply. It does this by examining the state of the powerGood Boolean variable (see earlier) and, if found to be FALSE (in other words, not good) the ‘power good’ LED is turned ‘off’ by writing a low (0V) to its digital output pin (pin-11 as defined within the integer declaration earlier in the code). The syntax for the declaration (in this particular case it’s a constant rather than a variable) is simply the name followed by the value that you’ve assigned to it. Note that the name takes the form of a meaningful description (two words with no space included between them). Note also that the first word begins with a lower-case character and the second word with a single upper-case character. This convention helps make the code easier to read and it avoids the need to include a space character in the name (which would be invalid). At some point later in the code you might find something like this:
if(powerGood = = FALSE) { digitalWrite(powerLED, LOW); }
There’s often a need to increment or decrement a variable within a program loop (for example, when counting events) but, because of the use of two’s complement notation, it is very important to be aware that when a variable is incremented or decremented the value will roll-over whenever it reaches the maximum allowable size. So, for example, incrementing 32767 (the maximum allowable positive value) will cause the value to become –32768 (note the change of sign). In a similar manner, decrementing a value of –32768 (the maximum allowable negative value) will cause a variable to take a new value of +32767. Finally, please be aware that the use of two bytes to store an integer is not consistent over all Arduino versions. For example, the Arduino Due uses four bytes (32-bits) to store integer values. This provides a range of values extending from –2,147,483,648 to +2,147,483,647.
Floating point data As the name implies, floating point numbers, or ‘floats’, are numbers that include a decimal point. They offer a much larger range from –3.4028235 × 10 38 to +3.4028235 × 10 38. Floats are stored using four bytes (32 bits) of data. Floats are often used to represent analogue values from sensors. Due to the need for four bytes of data, floating point maths can be significantly slower than when integers are used (where only two bytes of data are involved). Consequently, it is advisable to use integers rather than floats whenever speed of execution is important. A typical extract from a program’s setup code might be:
float peakConvert = 1.4142; // To convert from // RMS to peak
We could then determine the peak voltage and peak current present in a 50Ω load using something of the form:
peakVoltage = rmsVoltage * peakConvert; peakCurrent = peakVoltage / 50;
Byte data Byte data stores 8-bits of data as unsigned binary numbers. So, for example, a binary value of 10000001 (equivalent to 81 in hexadecimal or 129 in decimal) might be defined as follows:
byte bitMask = 0x81; // mask unwanted bits
Note that the 0x prefix denotes a value expressed in hexadecimal (base 16) format. Because only eight bits are used, byte data is limited in range. The minimum value that can be represented is 0 when all of the bits are 0 (hexadecimal 0x00) and the maximum value is 255 (hexadecimal 0xFF) when all of the bits are set to 1. Despite the restricted range, byte data can be useful in a variety of applications, particularly when dealing with the status of byte-wide (ie, eight-bit) input or output lines. For example:
byte inputStatus = 0x00; // initialise // input port status byte inputFailure = 0xFF; // all port lines // have gone high
At some later point in the code we might encounter a line of the form:
if(inputStatus = = inputFailure) { Serial.print(“Warning: Input failure!”); }
In this example, a fault is present if all of the input lines are simultaneously in the HIGH state and in this condition the value of the inputStatus variable will be 0xFF, If this condition is detected a brief warning message will be sent from the Arduino’s serial port.
Character data The character data type is used when we just need to represent alphanumeric information such as plain text. The character data type uses a single byte of memory to store each character. Thus, the word ‘character’ would need nine bytes of storage. Character literals are enclosed within single quotes (eg, ‘A’) while double quotes are used for strings comprising several characters (eg “Arduino”). Character data is encoded using the American Standard Code for Information Interchange (ASCII). Each character is represented by a corresponding signed 8-bit value. ‘A’ for example is encoded as 01000001 in binary. This is equivalent to 41 in hexadecimal or 65 in decimal 65. The basic ASCII character set uses only seven bits (equivalent to a decimal range that extends from 0 to +127. When the leading bit is set (ie, 1 and not 0) the signed byte becomes negative with a range extending from –1 to –128. These 128 values can be used to represent special characters. Note that each of the following three lines of code are equivalent:
char testChar = ‘A’; char testChar = 65; char testChar = 0x41;
Note how the number base in the last example is indicated by the prefix 0x which indicates that the number that follows is written in hexadecimal format. The Serial.println() function provides you with a way of printing data using several different representations, as shown in the following code:
Serial.println(analogValue); // print ASCII character Serial.println(analogValue, DEC); // print as ASCII-encoded // decimal Serial.println(analogValue, HEX); // print as ASCII-encoded // hex Serial.println(analogValue, OCT); // print as ASCII-encoded // octal Serial.println(analogValue, BIN); // print as ASCII-encoded // binary
You will find an example of the use of serial printing in this month’s Arduino World. This concludes our brief look at the way that data is represented in an Arduino environment. Next month, we will get to grips with decisions and how to make them, as well as explaining how program code is structured and laid out.
An Edit/View window can be opened to allow you to see and edit a syntax- highlighted version of your user program. Errors during simulated execution (such as mismatched baud rates) are reported on the status bar, and via a pop-up message box. UnoArduSim V1.1 is a substantially complete implementation of the Arduino programming language V1.0.6, as documented on the official Arduino website. While UnoArduSim does not support the full C++ implementation present in the Arduino IDE and its underlying GNU compiler, it is likely that only the most advanced programmers would discover something they wished to use was missing. It is usually possible to avoid problems with simple work-arounds.
Listing 4
/* Use serial printing to produce an ASCII table with values shown in decimal, hex, octal and binary */
int i; // loop counter char testValue;
void setup() { // open the serial port at 9600 bps: Serial.begin(9600); Serial.print(“ASC”); Serial.print(“\t”); Serial.print(“Dec”); Serial.print(“\t”); Serial.print(“Hex”); Serial.print(“\t”); Serial.print(“Oct”); Serial.print(“\t”); Serial.print(“Bin”); Serial.print(“\n”); for (i = 0; i <= 63; i++) { testValue = 64 + i; Serial.print(testValue); // print ASCII char Serial.print(“\t”); Serial.print(testValue, DEC); // print decimal Serial.print(“\t”); Serial.print(testValue, HEX); // print hex Serial.print(“\t”); Serial.print(testValue, OCT); // print octal Serial.print(“\t”); Serial.print(testValue, BIN); // print binary Serial.print(“\n”); delay(250); } }
void loop() { }
Because UnoArduSim is a high- level-language simulator, only C/C++ statements are supported – assembly language statements are not. Similarly, because it is not a low-level machine simulation, ATmega328 registers are not accessible for either reading or writing, although register-allocation, passing and return are emulated when selected from within the Options menu. UnoArduSim is currently only available for the Windows platform, but porting the software to Linux, MacOS or Java might be a project for the future. You can download the installation software from: https://www.sites.google.com/ site/unoardusim/services Finally, Fig.1.21 shows UnoArduSim running a sketch that displays a table of ASCII character data (see Coding Quickstart ) with the program’s output displayed using the Serial Monitor window – see Listing 4.
Next month In next month’s Teach-In 2016 we will look at methods of connecting real- world hardware. To this end, Arduino Workshop deals with driving external loads, while Arduino World looks at a range of shields and add-on interface
Arduino World : Getting started
with an UnoArduSim______________________
If you don’t have an Arduino to hand you can still develop and test your code with a variety of virtual I/O devices using an Arduino simulator and one of the best of these is UnoArduSim, an excellent freeware real-time simulator developed by Dr Stan Simmons at Queen’s University in Ontario, Canada. UnoArduSim is designed for the student and Arduino enthusiast. It allows you to experiment with, and to easily debug Arduino programs without the need for any physical hardware devices. You can choose from a variety of virtual I/O devices, configure and connect them to a virtual Arduino Uno using the Lab Bench Pane. There’s no need to worry about wiring errors, misconnections or faulty devices while developing your code. UnoArduSim provides simple error messages for any parse or execution errors it encounters, and allows debugging with Reset, Run, Run-To, Halt, and flexible stepping in the Code Pane. This provides a simultaneous view of all global and currently-active local variables, arrays, and objects in the Variables Pane. Run-time array-bounds checking is provided, and internal RAM overflow will be detected and the culprit program line highlighted. Any electrical conflicts with attached I/O devices are flagged and reported as and when they occur. Arduino source code files (INO or PDE) are loaded into the program Code Pane. The program is then parsed, and ‘compiled’ into a tokenised executable which is then ready for simulated execution (note that, unlike the Arduino’s Integrated Development Environment, a standalone binary executable is not created). Any parse errors are detected and flagged by highlighting the line that failed to parse, and reporting the error on the status bar at the very bottom of the UnoArduSim application window. This is an extremely useful feature.
using one or more miniature relays (see Fig.2.2). These electromechanical devices comprise a coil wound on a high-permeability core and a moving armature mechanically linked to a set of contacts that make and break when the device is actuated (see Fig.2.3). When sufficient current is applied to the coil of the relay the resulting magnetic field will cause the soft iron armature to pull-in and this in turn will open or close the relay’s electrical contacts. A typical miniature PCB-mounted relay will operate from a 5V DC supply and its contacts will pull-in at typically 75% of this value. The specifications of such a relay are listed in Table 2.1. It is important to note from Table 2. that the relay coil requires an operating current that’s well beyond the output drive capability of the Arduino. We therefore need an interface that will provide the extra current required. Fortunately, this can often be little more than a low-power transistor and a handful of other components, as shown in Fig.2.4. In Fig.2.4 the transistor can be almost any NPN type with a current gain of around 100, or more. Diode D1 counters the effects of the induced voltage that will appear across the relay coil as the current (and consequently the magnetic
Nominal operating voltage 5V DC
Nominal operating current 73mA
Maximum load rating AC 250V 10A, DC 30V 10A Pull-in voltage (typical) 3.8V
DC coil resistance 70 Ω Power consumption (typical) 0.36W
Operating time (max.) 10ms Release time (max.) 5ms
Contact resistance (max.) 0.11 Ω
Operating life 100,000 operations at rated load Maximum switching rate 30 operations per second
Table 2.1 Electrical specifications of a typical miniature PCB-mounting relay
Fig.2.4. Simple single-transistor relay interface
Fig.2.3. Internal arrangement of a typical relay showing the coil, armature and contacts
Arduino World: Relay boards______________________
Many simple control projects can be based on a ready-made relay board, avoiding the need to construct your own interface circuit. Fortunately, there are quite a few to choose from and the two most common types are fitted with either four or eight relays, with each relay having its own driver circuit.
Four-channel relay board Fig.2.5 shows a typical four-channel relay board. The board has a transistor driver and an opto-isolator for each output channel. Similar boards can be purchased very cheaply (often less than £5) and so it is invariably more cost effective to purchase one of these boards rather than attempt to build one yourself. Individual relays are normally fitted with single-pole changeover contacts (equivalent to an SPDT switch) and are commonly rated 250V AC at 10A or 30V DC at 10A. Inputs are usually TTL compatible and active low (in other words, they require a logic 0 output from the Arduino to operate).
Isolation Many relay boards (like the one shown in Figs. 2.6) incorporate opto-isolators and this makes it possible to isolate the relay driver circuitry from the Arduino’s circuitry (see Fig.2.7). However, in many applications this feature will not be required and the relay driver circuitry can then be operated from the same supply and ground connection as used by the Arduino itself.
Relay board connection In Fig.2.8(a) the +5V and GND connections are common between the Arduino and the relay board. In this arrangement the relays must be 5V types and the only isolation between the Arduino and the load will be that afforded by the relay alone. This will usually be perfectly adequate for most applications, including switching mains loads at currents of up to several amps. Fig.2.8(b) shows how higher-voltage (eg, 12V or 24V) relays can be used, while retaining a common ground (GND)
Fig.2.6. Transistor drivers and optical isolators on the four-channel relay board
Fig.2.5. A four-channel relay interface board
flux) collapses when the transistor reverts from a conducting to a non-conducting state. A typical value for R1 would be 2.2kΩ when using a relay coil that requires less than 200mA to operate (eg, a 700 Ω coil rated at 12V). This value for R1 is sufficiently small to ensure that TR1 is driven into saturation when a high-state output voltage appears on the digital I/O line, but large enough to reduce the demand on the I/O port to around 2mA. A neater alternative to using discrete components is the use of an integrated circuit output driver, such as the popular ULN2803. We will be looking at this chip in a future Teach- In 2016 article, but for the moment, if you only have a couple of high current/ high voltage loads to drive then a simple discrete circuit like the one shown in Fig.2.4 is all that you need.
connection between the Arduino and the relay board. Higher power relays can be used for applications that involve switching currents of up to 20A. In all cases it is important to check the specifications of the relay that you plan to
Fig.2.7. Complete circuit of a four-channel relay board
Fig.2.8. Three possible relay board configurations providing different amounts of isolation
Fig.2.9. An eight-channel relay interface board
use and verify its suitability for use in a particular application. In Fig.2.8(c) we have shown a fully optically isolated arrangement in which there is no common ground connection between the Arduino and the relay board. This arrangement offers the greatest amount of isolation, together with improved noise immunity.
Eight-channel relay board Fig.2.9 shows an eight-channel relay board. Like the four- channel board that we’ve just described, boards of this type are also available at low-cost from several sources. At under £10 they offer an extremely cost-effective means of controlling up to eight loads and at a cost that’s considerably less than the cost of purchasing the individual components.
Coding relay outputs Fortunately, it’s very easy to control one or more relays using just a few lines of simple code. First, you will need to make sure that you define the digital output pins to which the relays are connected using a line of the form:
int pump = 5; // Pump connected via a relay on digital pin- int heater = 6; // Heater connected via a relay on digital pin-
Next, you will need to add a couple of lines into the setup() code block, as follows:
pinMode(pump, OUTPUT); // Pump is configured as an output pinMode(heater, OUTPUT); // Heater is configured as an output
The relays and their respective loads can be turned on and off incorporating the following lines of code at appropriate points in the main program loop:
Listing 2.2: Using a compound if ... then construct
/* Simple decision making using a compound if..then construct */
int redLED = 13; // red LED on digital pin 13 int greenLED = 12; // green LED on digital pin 12 int inAnalogue = A0; // analogue input pin 0 int inVoltage = 0; // initialise the variable
void setup() { pinMode(redLED, OUTPUT); pinMode(greenLED, OUTPUT); }
void loop() { // get the input voltage inVoltage = analogRead(inAnalogue); // illuminate the green or red status LEDs if (inVoltage >= 512){ digitalWrite(redLED, HIGH); digitalWrite(greenLED, LOW); } else{ digitalWrite(greenLED, HIGH); digitalWrite(redLED, LOW); } }
a == b a is equal to b True if a and b have the same value
a != b a is not equal to b True if a and b have different values
a > b a is greater than b
True if a is larger than b (but not true if they have the same value)
a < b a is less than b True if a is smaller than b (but not true if they have the same value)
a >= b a is greater than or equal to b
True if a is larger than b (and also true if they have the same value)
a <= b a is less than or equal to b
True if a is smaller than b (and also true if they have the same value)
Table 2.2 Conditions
Conditions In the last example you should have noticed the >= condition that we used to find out whether the input voltage has exceeded the threshold value of 512. The ‘greater than or equal to’ condition isn’t the only one that we have to play with, as Table 2.2 shows.
The while construct The while construct provides you with a means of continuously executing one or more statements until a condition evaluates false. The loop containing the statement (or statements) will continue to be executed as long as the condition remains true – but, as soon as it becomes false the loop will terminate and execution will continue
with the next subsequent statement. The basic syntax is:
while (conditional expression){ // statements to be executed if true, // each ending with ; }
Here’s an example that shows how a belt motor could be controlled using a while loop. The belt motor will run for as long as it takes for an item placed on the belt to reach a limit switch. Note that we must check the status of the limit switch inside the loop. If we forget to do this the motor will run forever!
while (limitSwitchStatus == LOW){ // Limit not reached so run the motor digitalWrite(motorRun, HIGH); // Check to see if anything has changed? limitSwitchStatus = digitalRead(limitSwitch); }
By making the conditional expression dependent on the value of a counter modified inside the loop we have a simple means of performing one or more statements a predetermined number of times, as follows:
Fig.2.10. Using UnoArduSim to simulate the execution of Listing 2.
count = 0; while(count < 50){ // code to be executed 50 times // each statement ending with ; count = count+1; }
In this wait loop we increment the counter on every pass through the loop until it reaches 50, at which point the conditional expression evaluates to false and execution continues with the next statement in the code. Note this neater way of incrementing the count value, as follows:
count = 0; while(count < 50){ // code to be executed 50 times // each statement ending with ; count++; }
In this case, count++ is used to ‘post-increment’ the value of count. In other words, it takes the current value of count, adds one to it and places the new value back into the count variable. Finally, here’s an example showing how a simple wait loop could be used to flash an alarm LED ten times:
flashCount = 0; while(flashCount < 10){ digitalWrite(alarmLED, HIGH); delay(500); // wait half a second digitalWrite(alarmLED, LOW); delay(500); // wait half a second flashCount++; }
The do ... while construct The do ... while loop works in a similar fashion to the while loop, but with the exception that the condition is tested at the end of the loop, not the beginning. This means that the statements within the loop will always be executed at least once. The syntax is as follows:
do { // code to be executed at least once, // each statement ending with ; } while (conditional expression);
Here’s an example of reading a pressure sensor and allowing it a short time for its output to reach a steady value:
do { delay(100); // wait for the value to settle cp = readPressure(); // read the pressure sensor } while (x < 10);
In this example we are calling the readPressure() function 10 times before arriving at the final value returned from the sensor.
The for loop construct The for loop is widely used in almost every computer language, and C is no exception. The construct is used to repeat a statement (or series of statements) whenever a condition evaluates true. If the condition evaluates false then the loop is exited and execution continues with the statement that immediately follows the loop. The for loop must be initialised at the outset and thus is a little more complex than the while loop. The basic syntax is:
for (loop initialization, conditional expression, increment){ // statements to be executed if true, // each ending with ; }
As with the while loop, a counter is often used to control the loop and this is incremented or decremented each time round the loop. This makes the construct ideal for use in any repetitive application, for
example, checking the status of a number of I/O lines. It is important to remember that loop initialisation occurs only once and before the loop is executed for the first time. The next code fragment shows how the ASCII character set can be sent to the serial printer. Note that, for this to run, we would first need to initialise the serial port interface using a line such as Serial. begin(9600). Note also that we have declared the count variable, i, within the loop initialisation itself.
for (int i = 0; i <= 63; i++) { testValue = 64 + i; Serial.print(testValue); Serial.print(“\n”); delay(100); }
Program structure and layout By now you should have gained some idea of what Arduino code looks like and how it is structured but before we go any further it is well worth explaining the layout of a C program in a little more detail. You may have noticed that the first few lines of code in a program usually take the form of a heading enclosed between pairs of characters, /* and */, which constitute a comment block. Everything between these two characters is taken as plain text and, since this has no effect on program execution you can use as many lines of text here as you want. The title comment block is usually followed by a number of variable declarations. The reason behind this is simply that, in the C language, variables must always be declared before they are used. In fact, declarations don’t have to be placed at the beginning of the program code but the point at which they are declared (ie, their position in the program) can impose restrictions on the scope over which they can be used. However, since we often need to use variables on a global basis (ie, anywhere in our program code) we will often place them before any of the other code. Declarations involve assigning a variable type (see last month), a name and (optionally) an initial value. Next follows code that’s used for setting up. This code is placed in a function called setup() and it is executed at the beginning and only once. The setup() function is often used to specify the pin modes (ie, input or output) and to configure the Arduino’s serial monitor, but if they are not being used the setup() function can simply be left empty. The main program code is written inside a loop that executes forever (or until the reset button is pressed or the power is removed). This loop() function contains the functions that will execute when the program is being run. Each function takes the form of a block of code that is executed whenever the function is called. Functions can be the ones that are built into the language or they can be user-defined. This feature allows us to extend the basic language for our own needs with our user-defined functions calling other functions (both user-defined and in-built) as and when required. Function declarations take the form of one or more statements enclosed between curly braces, { and }. Note that each individual statement must end with a semi-colon, ;. As well as the block comments that we mentioned earlier, comments can be placed in-line. These consist of plain text appearing after two // characters and added at the end of the line to which they apply. As previously mentioned, comments provide us with a useful reminder of what’s going on in the code and they can be invaluable when maintaining and debugging a program.
Fig.2.11. A simple Arduino program with various structural features identified
The input to digital I/O pin-7 is effectively a closed-circuit loop which, when broken, triggers the alarm. In a retail environment this can take the form of a continuous loop of insulated wire attached to any products that need to be protected. In order to remove an item the loop must be broken and this, in turn,
will trigger the alarm. In other applications the loop can comprise o n e o r m o r e m a g n e t i c a l l y o p e r a t e d p r o x i m i t y s w i t c h e s , a s s h o w n i n Fig.2.15. These are designed for discrete protection of doors and windows and they comprise a pair of moulded parts that need to be mounted adjacent to one another when the door or window to which they are attached is in the closed position. A permanent magnet is enclosed in one of the mouldings and a magnetic reed
Fig.2.12. Circuit of the simple Arduino-based security system
switch is mounted in the other. Proximity switches normally have a sensing range of between 10mm and 15mm and they are ideal for use in a range of basic security applications.
Code Listing 2.3 shows the complete code for the simple Arduino-based security system. To help you understand what’s going on we’ve included numerous comments in the code. Note that the main loop contains three while loops. The first of these waits for the alarm to be set (using S1). The second waits for the alarm to be triggered (when the zone loop is broken) and the third waits for the alarm to be cancelled (using S2). The two LEDs indicate as shown Table 2.3. As before, the code should be entered using the Arduino’s IDE and then saved before compiling and uploading it to the Uno, as described in last month’s Arduino Workshop. Don’t forget to save your work by clicking on ‘File’ and ‘Save’ or ‘Save As…’ when you finish. Next, click on ‘Sketch’ a n d ‘ Ve r i f y / C o m p i l e ’. Where errors occur during compilation they often arise from missing semi-colons or incorrectly matched pairs of curly brackets. Note also the use of two equality signs (==) in the conditional loop statement. The compiler will fail if you only use one of them.
Testing When you’ve corrected any coding errors that the compiler reports you will be ready to upload your code to the Uno. Just click on the upload arrow and watch
Fig.2.13. Fritzing breadboard arrangement for Fig.2.
Fig.2.14. Actual breadboard arrangement
Fig.2.15. Some common types of proximity switch
Fig.2.16. Using UnoArduSim to simulate the execution of Listing 2.3 (note that we’ve selected rising-edge triggering for digital inputs 11 and 12)
the progress report – but, before you do this it is important to make sure that the input loop is closed. The LEDs on the Uno should flash and the code should begin to execute. At this point neither of the status indicators, D1 and D2, should become illuminated. If you now press the SET button the green LED, D1, should become lit. This indicates that the alarm has been SET.
If you now break the loop the alarm will be triggered. In this condition the red status LED should be illuminated and the piezoelectric sounder should be operating. To reset the alarm you can press the CANCEL button, S2. Note that the alarm cannot be cancelled if the loop is still broken. To re-instate the alarm you will need to close the loop again, press the CANCEL button and, if all is well the red LED will go out and the circuit will then be ready to be put back into the SET state.
Going further There’s a great deal of scope for going further with our simple Arduino- based security alarm. The most obvious enhancement would be the addition of several more zones, each with an LED to indicate which of the zones has been triggered. All this needs is more of the digital I/O lines configured as inputs and outputs (one pair for each additional zone) together with some code that will poll each of the loops in turn to see if any of them have been triggered. Another useful modification would be an entry/exit delay that would operate on the zone associated with access. This would allow an entry door to be opened and closed without triggering the alarm for a short period after pressing the SET button. For applications in which a mains-operated sounder or floodlighting is to be controlled, the output from the piezoelectric sounder can be connected to a relay interface or a ready-made relay board like those described earlier in this month’s Teach In 2016. All of this makes this simple project an excellent candidate for further experimentation.
Next month In next month’s Teach-In 2016 we will look at displays and keyboards that can be used with the Arduino. To this end, Arduino Workshop deals with interfacing an alphanumeric LCD display and Arduino World looks at keypads and buttons. Our programming feature, Coding Quickstart , introduces string and string manipulation and the functions that you will need to read and print lines of text. Finally, Get Real will show you how to build a simple entry/access control system.
PICs?
Can anyone help me?
I Can help!
General Electronics chat
Problem sourcing software?
Upgrade your Arduino Electronics to the Next Generation with
As powerful as the Arduino Uno but smaller than a 2 pence coin. Available from our eShop
All the power of the Arduino in a fraction of the space, great for building intelligence in to your projects.
As an authorised reseller with an educational and training focus we can support all aspects of this outstanding piece of kit!
Get yours today via our eShop
Complete with a wide and growing range
project take you? Move up to the Next Generation!
Fantastic for schools especially D&T and Computing, meets the new requirements
Get the answer you’ve been looking for
PICs?
Can anyone help me?
I Can help!
General Electronicschat
Problem sourcing software?
PICs?
Can anyone help me?
I Can help!
General Electronics chat
Problem sourcing software?
PICs?
Can anyone help me?
I Can help!
General Electronics chat
Problem sourcing software?
PICs?
Can anyone help me?
I Can help!
General Electronics chat
Problem sourcing software?