This document provides an overview of embedded systems and microcontrollers. It defines embedded systems as computing systems designed to perform dedicated functions within larger devices. Billions of embedded systems are produced each year for uses like consumer electronics, appliances, automobiles, and more. The document compares microprocessors and microcontrollers, noting that microcontrollers are optimized for compact size and low cost by integrating memory and I/O on a single chip, making them well-suited for embedded applications. It also briefly introduces programming languages and notes that low-level languages require little abstraction from the hardware.
This document provides an overview of embedded systems and microcontrollers. It defines embedded systems as computing systems designed to perform dedicated functions within larger devices. Billions of embedded systems are produced each year for uses like consumer electronics, appliances, automobiles, and more. The document compares microprocessors and microcontrollers, noting that microcontrollers are optimized for compact size and low cost by integrating memory and I/O on a single chip, making them well-suited for embedded applications. It also briefly introduces programming languages and notes that low-level languages require little abstraction from the hardware.
Embedded System Computing systems are everywhere. Its probably no surprise that millions of computing systems are built every year destined for desktop computers (Personal Computers, or PCs), workstations, mainframes and servers. What may be surprising is that billions of computing systems are built every year for a very different purpose: they are embedded within larger electronic devices, repeatedly carrying out a particular function, often going completely unrecognized by the devices user. Creating a precise definition of such embedded computing systems, or simply embedded systems, is not an easy task. We might try the following definition: An embedded system is nearly any computing system other than a desktop, laptop, or mainframe computer. That definition isnt perfect, but it may be as close as well get. We can better understand such systems by examining common examples and common characteristics. Such examination will reveal major challenges facing designers of such systems. Embedded systems are found in a variety of common electronic devices, such as: Consumer Electronics -- cell phones, pagers, digital cameras, camcorders, videocassette recorders, portable video games, calculators, and personal digital assistants. Home Appliances -- microwave ovens, answering machines, thermostat, home security, washing machines, and lighting systems. Office Automation -- fax machines, copiers, printers, and scanners. Business Equipment -- cash registers, curbside check-in, alarm systems, card readers, product scanners, and automated teller machines. Automobiles -- transmission control, cruise control, fuel injection, anti-lock brakes, and active suspension. One might say that nearly any device that runs on electricity either already has, or will soon have, a computing system embedded within it. It may be surprising to hear that several billion embedded microprocessor units were sold annually compared to a few hundred million desktop microprocessor units. Embedded systems have several common characteristics: Single-functioned: An embedded system usually executes only one program, repeatedly. A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 2
Reactive and real-time: Many embedded systems must continually react to changes in the systems environment, and must compute certain results in real time without delay. Tightly constrained: A design metric is a measure of an implementations features such as cost, size, performance, and power. Embedded systems often must cost just a few dollars, must be sized to fit on a single chip, must perform fast enough to process data in real- time, and must consume minimum power to extend battery life or prevent the necessity of a cooling fan. In general we can conclude an embedded system as a special-purpose computer system designed to perform one or a few dedicated functions, often with real-time computing constraints. It is usually embedded as part of a complete device including hardware and mechanical parts. The program instructions written for embedded systems are referred to as firmware.
Microprocessor Vs Microcontroller Microprocessors are generally utilized for relatively high performance applications where cost and size are not critical selection criteria. Because microprocessor chips have their entire function dedicated to the CPU and thus have room for more circuitry to increase execution speed, they can achieve very high-levels of processing power. However, microprocessors require external memory and I/O hardware. Microprocessor chips are used in desktop PCs and workstations where software compatibility, performance, generality, and flexibility are important. By contrast, microcontroller chips are usually designed to minimize the total chip count and cost by incorporating memory and I/O on the chip. They are often application specialized at the expense of flexibility. In some cases, the microcontroller has enough resources on-chip that it is the only IC required for a product. The hardware interfaces of both devices have much in common, and those of the microcontrollers are generally a simplified subset of the microprocessor. The primary design goals for each type of chip can be summarized this way: Microprocessors are most flexible Microcontrollers are most compact
A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 3
There are also differences in the basic CPU architectures used, and these tend to reflect the application. Microprocessor based machines usually have a von Neumann architecture with a single memory for both programs and data to allow maximum flexibility in allocation of memory. Microcontroller chips, on the other hand, frequently embody the Harvard architecture, which has separate memories for programs and data.
(a) von Neumann architecture (b) Harvard architecture
In order to use a generic microprocessor in an embedded application you need to add some amount of external resource to be attached to it. These may include program memory (ROM) to save the program, data memory (RAM) to load variables during execution, timers, I/O ports, and communication ports such as Serial, Parallel etc, PWM, A/D converter etc which result in complex design. In contrast microcontrollers incorporate most of these in a single chip leading to fairly simple design. Most of the commonly available microprocessors today are 32 or 64 bit versions and with a clock speed of few GHz. Microprocessor make use of powerful instruction set (which need to include more hardware circuit inside the chip to help the execution of some instructions) and complex addressing modes. But many applications do not require the impressive power of the 32/64-bit microprocessor or the extensive expandability that is available on many microprocessor-based motherboards. In contrast a microcontroller incorporate most of the resources needed to run a custom application, including memory and peripheral such as I/O ports, Communication channels, timers etc. These controllers are available in a vast variety of choices. The designer has the freedom to select a controller which is suitable for the application to be designed. Since embedded systems are more cost sensitive, this freedom allows the designer to keep the cost to minimum by the right selection of controller. One could easily argue that the microcontrollers currently available do not compare to the powerful 32-bit microprocessors that can access billions of bytes of memory, have powerful instruction sets that support multitasking, are optimized for multimedia processing, and run at clock speeds upward from 2 GHz. On the other hand, it would be a waste of technology to put a 32-bit microprocessor inside a robot arm dedicated to welding frame joints on an assembly line or inside a credit card machine, microwave oven, or personal computer keyboard. In small, dedicated applications like these, an 8-bit microcontroller is powerful enough to handle the job with a Program Memory Program & Data Memory CPU Data Memory CPU A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 4
minimum of external circuitry. With its built-in EEPROM and RAM, serial I/O and timer capability, and self-contained operation, why use anything else for a small control application? It would be too expensive in terms of component count, layout, board space, and troubleshooting to use anything but a microcontroller. So which is the best choice a Microcontroller or a Microprocessor? The answer depends on the application that be designed.
Programming Language A programming language is an artificial language that can be used to write programs which control the behavior of a machine, particularly a computer. Programming languages are defined by syntactic and semantic rules which describe their structure and meaning respectively. Programming languages are also used to facilitate communication about the task of organizing and manipulating information, and to express algorithms precisely. Some authors restrict the term "programming language" to those languages that can express all possible algorithms; sometimes the term "computer language" is used for more limited artificial languages. A low-level programming language is a language that provides little or no abstraction from the processor or controller which runs the program. The word "low" refers to the small or nonexistent amount of abstraction between the language and machine language; because of this, low-level languages are sometimes described as being "close to the hardware". A low level language is one that does not need a compiler or interpreter to run. The processor for which the language was written would be able to run the code without the use of either of these. Low-level programming languages are sometimes divided into two categories: first generation, and second generation. The first-generation programming language, or 1GL, is machine code. It is the only language a microprocessor can understand directly. Currently, programmers almost never write programs directly in machine code, because not only does it (like assembly language) require attention to numerous details which a high-level language would handle automatically, but it also requires memorizing or looking up numerical codes for every instruction that is used. For this reason, second generation programming languages abstract the machine code one level. The second-generation programming language, or 2GL, is assembly language. It is considered a second-generation language because while it is not a microprocessor's native language, an assembly language programmer must still understand the microprocessor's A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 5
unique architecture (such as its registers and instructions). These simple instructions are then compiled directly into machine code. The assembly code can also be abstracted to another layer in a similar manner as machine code is abstracted into assembly code. A high-level programming language is a programming language with strong abstraction from the details of the computer. In comparison to low-level programming languages, it may use natural language elements, be easier to use, or more portable across platforms. Such languages hide the details of CPU operations such as memory access models and management of scope. A high level language isolates the execution semantics of a computer architecture from the specification of the program, making the process of developing a program simpler and more understandable with respect to a low-level language. The amount of abstraction provided defines how 'high level' a programming language is. The term "high-level language" does not imply that the language is always superior to low-level programming languages - in fact, in terms of the depth of knowledge of how computers work required to productively program in a given language, the inverse may be true. High-level languages make complex programming simpler, while low-level languages tend to produce more efficient code. Abstraction penalty is the barrier preventing applying high level programming techniques in situations where computational resources are limited. Ada, C, Python, Perl, Ruby, BASIC are some examples of high level language.
The C The C programming language is certainly the most influential in the world of programming. Created at first by Brian Kernighan and Dennis Ritchie in 1972, this language is characterized by its closeness to the hardware without being architecture dependent. Not that it is complicated (like Assembly), but you can move generally as you want in the memory for example, but may crash if you are not permitted to read or write to that memory. More than any other, C has become the language of embedded programmers. This has not always been the case, and it will not continue to be so forever. However, at this time, C is the closest thing there is to a standard in the embedded world. Of course, C is not without advantages. It is small and fairly simple to learn, compilers are available for almost every processor in use today, and there is a very large body of experienced C programmers. In addition, C has the benefit of processor-independence, which allows programmers to concentrate on algorithms and applications, rather than on the details of a particular processor A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 6
architecture. However, many of these advantages apply equally to other high-level languages. So why has C succeeded where so many other languages have largely failed? Perhaps the greatest strength of C-and the thing that sets it apart from languages like Pascal and FORTRAN-is that it is a very "low-level" high-level language. As we shall see throughout the book, C gives embedded programmers an extraordinary degree of direct hardware control without sacrificing the benefits of high-level languages. The "low-level" nature of C was a clear intention of the language's creators. In fact, Kernighan and Ritchie included the following comment in the opening pages of their book The C Programming Language: C is a relatively "low level" language. This characterization is not pejorative; it simply means that C deals with the same sort of objects that most computers do. These may be combined and moved about with the arithmetic and logical operators implemented by real machines. Few popular high-level languages can compete with C in the production of compact, efficient code for almost all processors. And, of these, only C allows programmers to interact with the underlying hardware so easily.
Other Embedded Languages Of course, C is not the only language used by embedded programmers. At least three other languages-assembly, C++, and Ada-are worth mentioning in greater detail. In the early days, embedded software was written exclusively in the assembly language of the target processor. This gave programmers complete control of the processor and other hardware, but at a price. Assembly languages have many disadvantages, not the least of which is higher software development costs and a lack of code portability. In addition, finding skilled assembly programmers has become much more difficult in recent years. Assembly is now used primarily as an adjunct to the high-level language, usually only for those small pieces of code that must be extremely efficient or ultra-compact, or cannot be written in any other way. C++ is an object-oriented superset of C that is increasingly popular among embedded programmers. All of the core language features are the same as C, but C++ adds new functionality for better data abstraction and a more object-oriented style of programming. These new features are very helpful to software developers, but some of them do reduce the efficiency of the executable program. So C++ tends to be most popular with large A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 7
development teams, where the benefits to developers outweigh the loss of program efficiency. Ada is also an object-oriented language, though it is substantially different than C++. Ada was originally designed by the U.S. Department of Defense for the development of mission-critical military software. Despite being twice accepted as an international standard (Ada83 and Ada95), it has not gained much of a foothold outside of the defense and aerospace industries. And it is losing ground there in recent years. This is unfortunate because the Ada language has many features that would simplify embedded software development if used instead of C++.
Arduino Arduino is a tool for making computers that can sense and control more of the physical world than your desktop computer. It's an open-source physical computing platform based on a simple microcontroller board, and a development environment for writing software for the board. Arduino can be used to develop interactive objects, taking inputs from a variety of switches or sensors, and controlling a variety of lights, motors, and other physical outputs. Arduino projects can be stand-alone, or they can communicate with software running on your computer (e.g. Flash, Processing, and MaxMSP). Why should we go for Arduino? There are many other microcontrollers and microcontroller platforms available for physical computing. There are available so many development / training kit for different microcontrollers like PIC, 8051, AVR etc. in the market. All of these tools take the messy details of microcontroller programming and wrap it up in an easy-to-use package. Arduino also simplifies the process of working with microcontrollers, but it offers some advantage for teachers, students, and interested amateurs over other systems: Inexpensive - Arduino boards are relatively inexpensive compared to other microcontroller platforms. Cross-Platform - The Arduino software runs on Windows, Macintosh OSX, and Linux operating systems. Most microcontroller systems are limited to Windows Simple, Clear Programming Environment - The Arduino programming environment is easy-to-use for beginners, yet flexible enough for advanced users to take advantage of as well A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 8
Open Source and Extensible Software- The Arduino software and is published as open source tools, available for extension by experienced programmers. The language can be expanded through C++ libraries, and people wanting to understand the technical details can make the leap from Arduino to the AVR C programming language on which it's based. Similarly, you can add AVR-C code directly into your Arduino programs if you want to. Open Source and Extensible Hardware - The Arduino is based on Atmel's ATMEGA8 and ATMEGA168 microcontrollers. The plans for the modules are published under a Creative Commons license, so experienced circuit designers can make their own version of the module, extending it and improving it. Arduino Programming Structure Like all other programming language Arduino programming also has a structure. The program can be divided in to three sections. In the first section we declare pins and other variables which are needed for the program. The second section is the setup section in which we configure the device pins and other peripherals. This section is handled by a function void setup (). The third and final section contains all our conditional logic that is going to be executed indefinitely until you turn the Arduino board off. The logic should be enclosed in the void loop () function. The following lines give you a better view of the structure. The syntax followed is same as that of C. Arduino programming is assisted with a set of built in functions for each of the controller specific activity. The rest part is common C. The following sections give you a better awareness of the programming of Arduino.
Blink an LED In most programming languages, the first program you write prints "hello world" to the screen. Since an Arduino board doesn't have a screen, we blink an LED instead. The boards are designed to make it easy to blink an LED using digital pin 13. To connect an LED to another digital pin, you should use an external resistor. LEDs have polarity, which means they will only light up if you orient the legs properly. The long leg is typically positive, and should connect to pin 13. The short leg connects to GND; the bulb of the LED will also typically have a flat edge on this side. If the LED doesn't light up, trying reversing the legs. The following code can be used to light the LED connected to pin 13. pinMode () is a built in A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 9
function used to declare the mode of a pin as input or output. digitalWrite () function will set a pin specified to one of the following states: HIGH, LOW.
# Program 1 //************** Blink an LED connected to pin 13 **************
int ledPin = 13; // LED connected to digital pin 13
void setup() { pinMode(ledPin, OUTPUT); // sets the digital pin as output }
void loop() { digitalWrite(ledPin, HIGH); // sets the LED on while(true); // stay here infinitely
while (1) is used in a program to tell the controller to keep executing the statement indefinitely. This is particularly useful in the troubleshooting of the program code. This program is the first code to run to test that your Arduino board is working and configured correctly. Type the code into your Arduino editor. Now that the code is in your IDE we need to verify it and upload it to the board. Press the Verify button and if everything is correct youll see the message Done compiling appear at the bottom of the program text. At this point we can upload it into the board: press the reset button on the Arduino board, this forces the board to stop what it is doing and listen for instructions coming from the serial port. Now we have about 6 or 7 seconds to press the Upload to I/O Board button. this sends the current program to the board that will store it in its memory and eventually run it. You will see a few messages appear in the black area at the bottom of the window, these are messages that make it easier to understand if the process has completed correctly.
Blink an LED using Delay This program will show you how to turn an LED on and off periodically. For this we use the built in function delay (). The delay function takes an integer value corresponds to millisecond value. To get a delay of 1 second we have to use a value of 1000 in delay (). The program is an extension of the above program. A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 10
# Program 2 //************** Blink an LED using delay **********************
int ledPin = 13; // LED connected to digital pin 13
void setup() { pinMode(ledPin, OUTPUT); // sets the digital pin as output }
void loop() { digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off delay(1000); // waits for a second while(true); // stay here
If we remove the while statement at the end of the loop section will be executed indefinitely and so the LED will blink infinitely in 1 second interval.
Control an LED using Pushbutton Switch The pushbutton is a component that connects two points in a circuit when you press it. The example turns on an LED when you press the button. We connect three wires to the Arduino board. The first goes from one leg of the pushbutton through a pull-up resistor to the 5 volt supply. The second goes from the corresponding leg of the pushbutton to ground. The third connects to a digital I/O pin (here pin 2) which reads the button's state. When the pushbutton is open (un pressed) there is no connection between the two legs of the pushbutton, so the pin is connected to 5 volts (through the pull-up resistor) and we read a HIGH. When the button is closed (pressed), it makes a connection between its two legs, connecting the pin to ground, so that we read a LOW. (The pin is still connected to 5 volts, but the resistor in-between them means that the pin is "closer" to ground.)
# Program 3 //************** Control LED using Pushbutton switch ***********
int ledPin = 13; // choose the pin for the LED int inPin = 2; // choose the input pin (for a pushbutton) int val = 0; // variable for reading the pin status
void setup() { pinMode(ledPin, OUTPUT); // declare LED as output A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 11
pinMode(inPin, INPUT); // declare pushbutton as input }
void loop() { val = digitalRead(inPin); // read input value if (val == HIGH) // check if the input is HIGH digitalWrite(ledPin, LOW); // turn LED OFF else digitalWrite(ledPin, HIGH); // turn LED ON }
You can also wire this circuit the opposite way, with a pull-down resistor keeping the input LOW, and going HIGH when the button is pressed. If so, the behavior of the program will be reversed, with the LED normally on and turning off when you press the button. If you disconnect the digital I/O pin from everything, the LED may blink erratically. This is because the input is "floating" - that is, it will more-or-less randomly return either HIGH or LOW. That's why you need a pull-up or pull-down resister in the circuit.
Loop Suppose we want to blink the LED for a pre defined number of times, how can we do that? Let us consider that we want to blink an LED for three times. The following code will show you how to achieve this. The program uses the same code for blinking an LED using delay.
# Program 4 //************** Blink an LED using delay **********************
int ledPin = 13; // LED connected to digital pin 13
void setup() { pinMode(ledPin, OUTPUT); // sets the digital pin as output }
void loop() { digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off delay(1000); // waits for a second
digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 12
delay(1000); // waits for a second
digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off delay(1000); // waits for a second
The while statement limit the blinking to three. If you examine the code you can notice that the same code is repeated three times in the loop section. If the count is comparatively less this method is useful but it still consume useful controller memory. If the count is high what will be the solution? Loops solves this problem to some extend. Some of the commonly used loops in programming are for and do while. Now we can examine how to rewrite the program to make use of for loop.
# Program 5 //************** Blink an LED using delay **********************
int ledPin = 13; // LED connected to digital pin 13 int i; // an integer variable
void setup() { pinMode(ledPin, OUTPUT); // sets the digital pin as output }
void loop() { for (i=1; i<=10; i++) { digitalWrite(ledPin, HIGH); // sets the LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // sets the LED off delay(1000); // waits for a second } while(true); // stay here
}
//************************************************************** Q. Try to modify the program using do while.
Blinking Multiple LED A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 13
This example make use of 6 LEDs connected to pin 2 -7 on the board using 220 resister. The code will blink the LED in a sequential manner starting with the one connected to pin number 2. the code uses a for loop.
# Program 6 //************** Blinking multiple LEDs ************************
int ms_time = 1000; // delay time in millisecond int pins[] = { 2, 3, 4, 5, 6, 7 }; // an array of pin numbers int num_pins = 6; // the number of pins (array length)
void setup() { int i; for (i = 0; i < num_pins; i++) pinMode(pins[i], OUTPUT); // set each pin as an O/P }
void loop() { int i;
for (i = 0; i < num_pins; i++) // loop through each pin { digitalWrite(pins[i], HIGH); // turning it on, delay(ms_time); // wait for 1 second digitalWrite(pins[i], LOW); // and turning it off. } } //**************************************************************
Q. Try to blink the LED in reverse order by editing the program.
Delay Control Using Potentiometer A potentiometer is a simple knob that provides a variable resistance, which we can read into the Arduino board as an analog value. In this example, that value controls the rate at which an LED blinks. We connect three wires to the Arduino board. The first goes to ground from one of the outer pins of the potentiometer. The second goes from 5 volts to the other outer pin of the potentiometer. The third goes from analog input 2 to the middle pin of the potentiometer. By turning the shaft of the potentiometer, we change the amount of resistance on either side of the wiper which is connected to the center pin of the potentiometer. This changes the relative "closeness" of that pin to 5 volts and ground, giving us a different analog input. When the shaft is turned all the way in one direction, there are 0 volts going to the pin, and we read 0. When the shaft is turned all the way in the other direction, there are 5 volts A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 14
going to the pin and we read 1023. In between, analogRead() returns a number between 0 and 1023 that is proportional to the amount of voltage being applied to the pin.
# Program 7 //************** Blinking control using potentiometer **********
int potPin = 2; // input pin for the potentiometer int ledPin = 13; // pin for the LED int val = 0; // variable to store the potentiometer value
void setup() { pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT }
void loop() { val = analogRead(potPin); // read the value from the sensor digitalWrite(ledPin, HIGH); // turn the ledPin on delay(val); // stop the program for some time digitalWrite(ledPin, LOW); // turn the ledPin off delay(val); // stop the program for some time }
The analogRaed function automatically configure the pin as input so there is no need to include it in setup phase.
Brightness control using Potentiometer For brightness control, we know that an analog signal is needed. But how can we generate an analog signal using a microcontroller. We all know that a microcontroller can only produce a digital value. The solution is to use a PWM signal. Pulse width modulation (PWM) is a powerful technique for controlling analog circuits with a processor's digital outputs. PWM is employed in a wide variety of applications, ranging from measurement and communications to power control and conversion. By controlling analog circuits digitally, system costs and power consumption can be drastically reduced. PWM is a way of digitally encoding analog signal levels. Through the use of high- resolution counters, the duty cycle of a square wave is modulated to encode a specific analog signal level. The PWM signal is still digital because, at any given instant of time, the full DC supply is either fully on or fully off. The voltage or current source is supplied to the analog load by means of a repeating series of on and off pulses. The on-time is the time during which the DC supply is applied to the load, and the off-time is the time during which that supply is switched off. Given a sufficient bandwidth, any analog value can be encoded with PWM. A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 15
One of the advantages of PWM is that the signal remains digital all the way from the processor to the controlled system; no digital-to-analog conversion is necessary. By keeping the signal digital, noise effects are minimized. Noise can only affect a digital signal if it is strong enough to change a logic-1 to a logic-0, or vice versa. Increased noise immunity is yet another benefit of choosing PWM over analog control, and is the principal reason PWM is sometimes used for communication. Switching from an analog signal to PWM can increase the length of a communications channel dramatically. At the receiving end, a suitable RC (resistor-capacitor) or LC (inductor- capacitor) network can remove the modulating high frequency square wave and return the signal to analog form. The controller used in the Arduino is ATMEGA8 from ATMEL. The controller offers a PWM module. The function analogWrite() take care of the module and the following code shows the usage.
# Program 8 //************** Brightness control using potentiometer *********
int potPin = 2; // input pin for the potentiometer int ledPin = 13; // pin for the LED int val = 0; // variable to store the potentiometer value
void setup() { pinMode(ledPin, OUTPUT); // declare the ledPin as an O/P }
void loop() { val = analogRead(potPin); // read analog value analogWrite(ledPin, val); // write the value delay(50); // wait to see the effect }
Q. Write a program to automatically fade in and fade out an LED. Q. Write a program to control the speed of automatic fading using two push button switches, one for increasing and other for decreasing speed.
Serial Communication Serial communication is a way enables different equipments to communicate with their outside world. It is called serial because the data bits will be sent in a serial way over a single line. A personal computer has a serial port known as communication port or COM Port used to connect other device. Serial ports are controlled by a special chip called UART (Universal Asynchronous Receiver Transmitter). Different applications use different pins on A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 16
the serial port and this basically depend of the functions required. If you need to connect your PC for example to some other device by serial port, then you have to read instruction manual for that device to know how the pins on both sides must be connected and the setting required. Serial communication has some advantages over the parallel communication. One of the advantages is transmission distance, serial link can send data to a remote device more far then parallel link. Also the cable connection of serial link is simpler then parallel link and uses less number of wires. Serial link is used also for Infrared communication, now many devices such as laptops & printers can communicate via inferred link. There are two methods for serial communication, Synchronous & Asynchronous. In Synchronous serial communication the receiver must know when to read the next bit coming from the sender, this can be achieved by sharing a clock between sender and receiver. Asynchronous transmission allows data to be transmitted without the sender having to send a clock signal to the receiver. Instead, special bits will be added to each word in order to synchronize the sending and receiving of the data. Most microcontroller communication implements asynchronous serial communication method with PC. This is because the standard serial communications hardware in the PC does not support Synchronous operations. We will now discuss this in detail. When a word is given to the UART for Asynchronous transmissions, a bit called the "Start Bit" is added to the beginning of each word that is to be transmitted. The Start Bit is used to alert the receiver that a word of data is about to be sent, and to force the clock in the receiver into synchronization with the clock in the transmitter. After the Start Bit, the individual bits of the word of data are sent, each bit in the word is transmitted for exactly the same amount of time as all of the other bits. When the entire data word has been sent, the transmitter may add a Parity Bit that the transmitter generates. The Parity Bit may be used by the receiver to perform simple error checking. Then at least one Stop Bit is sent by the transmitter. If the Stop Bit does not appear when it is supposed to, the UART considers the entire word to be garbled and will report a Framing Error.
Baud Rate Baud rate is a measurement of transmission speed in Asynchronous Communication. It represents the number of bits that are actually being sent over the serial link. The Baud count includes the overhead bits Start, Stop and Parity that are generated by the sending UART and removed by the receiving UART. A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 17
ASCII ASCII stands for American Standard Code for Information Interchange. It is a character encoding based on the English alphabet. ASCII codes represent text in computers, communications equipment, and other devices that work with text. ASCII includes definitions for 128 characters encoded in 7 bits. The ASCII character encoding or a compatible extension (Unicode) is used on nearly all common computers, especially personal computers and workstations. ASCII reserves the first 32 codes (0x00 to 0x1F) for control characters: codes originally intended not to carry printable information, but rather to control devices. Code 32, the "space" character, denotes the space between words, as produced by the space-bar of a keyboard. The "space" character is considered an invisible graphic rather than a control character. Codes 33 to 126, known as the printable characters, represent letters, digits, punctuation marks, and a few miscellaneous symbols. Hello World We have seen at the beginning of the booklet that Arduino has a serial connection that is used by the IDE to upload code into the processor. The good news is that this connection can also be used by the programs that we write in Arduino to send data back to the computer or receive commands from it. For this purpose we are going to use the Serial object. This object contains all the code we need to send and receive data. The following example shows the basic command required for establishing serial communication. The program will send Hello World!!! to the serial terminal of the IDE.
# Program 9 //************** Serial communication Hello World!!! **********
void setup() { Serial.begin(9600); // open the serial port to send data @ 9600 Baud }
//************************************************************** A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 18
Now that we have the program running you should press the Serial Monitor button on the Arduino IDE and youll see Hello World!!! printed at bottom part of the window. Now any software that can read from the serial port can talk to Arduino.
Character Handling For reading a character available at serial port Arduino provide a built in function called Serial.read (). This function will read a character available at serial buffer of Arduino board. For checking whether a character is available there is another function Serial.available (). The function will check if a character is available in the serial buffer or not. If there is a character it will return a non zero value else zero. The following program will receive a character pressed in the keyboard and display it on the serial terminal program like HyperTerminal.
# Program 10 //************** Character Echoing Serial Rx an Tx ************** char value; //variable for saving keyboard character
void setup() { Serial.begin(9600); // open the serial port to send data @ 9600 Baud } void loop() { Serial.print( Character Echoing Program \n); while(1) { if(Serial.available()) // check character availability { Value = Serial.read(); //if available copy to value Serial.print(value); // print the char to terminal } } } //**************************************************************
Hardware / Sensor Interface Interfacing the LCD Its very simple to interface an LCD module with Arduino. The only thing we need to know is the controlling and data pins of LCD. Lets take a look in to the 2x16 LCD module, which is very commonly available in the market. 2x16 means that the LCD module has 2 lines of 16 characters each. The module will have 14 pins. The pin description is as follows. A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 19
Pin Symbol I/O Description 1 GND - Ground 2 Vcc - +5V Power Supply 3 VEE - Contrast Control 4 RS I Command / Data Register Selection 5 R/W I Write / Read selection 6 E I/O Enable Pin 7 DB0 I/O Data pin 0 8 DB1 I/O Data pin 1 9 DB2 I/O Data pin 2 10 DB3 I/O Data pin 3 11 DB4 I/O Data pin 4 12 DB5 I/O Data pin 5 13 DB6 I/O Data pin 6 14 DB7 I/O Data pin 7
There are also instructions command codes that can be sent to the LCD to clear the display or force the cursor to the home position or blink the cursor. Table below lists the instruction command codes. Code (hex) Command to LCD Instruction Register 1 Clear display screen 2 Return home 4 Shift cursor to left 5 Shift display right 6 Shift cursor to right 7 Shift display left 8 Display off, Cursor off A Display off, Cursor on C Display on, cursor off E Display on, cursor blinking F Display on, cursor blinking 10 Shift cursor position to left 14 Shift cursor position to right 18 Shift the entire display to the left 1C Shift the entire display to the right 80 Force cursor to beginning of 1st line C0 Force cursor to beginning of 2nd line 38 2 lines and 5x7 matrix
We also use RS = 0 to check the busy flag bit to see if the LCD is ready to receive information. The busy flag is D7 and can be read when R/W =1 and RS = 0, as follows: if R/W =1, RS =0. When D7 = 1(busy flag = 1), the LCD busy taking care of internal A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 20
operations and will not accept any new information. When D7 = 0, the LCD is ready to receive new information. Note: It is recommended to check the busy flag before writing any data to the LCD. The good thing is that for an Arduino user, he or she doesnt need to take in to account these things since there available library built for LCD for this platform. The programmer can directly use this library and only need to know the LCD pins used by the library (i.e., the data and control lines necessary for interfacing which are DB0-DB7, RS, R/W and E ). Library using 8 data lines and 4 data lines are available. Using 8 data pins for an LCD reduces the Arduino digital pins available for other use. For an interface using 8 data lines which required 11 Arduino pins. So we go ahead with a 4 bit interface library which requires only 7 Arduino pins. The library is already added to the distribution given to you. Some of the functions in the library are init() : initialize the LCD print(string) : print a string on LCD clear() : Clear LCD display cursorTo(line no, position) : Move the cursor to the specified position leftScroll(no of positions, delay) : Scroll characters to left with specified delay.
# Program 11 //************** Interfacing LCD with Arduino - 4 Bit Version ** #include <LCD4Bit.h> LCD4Bit LCD = LCD4Bit(1); //number of lines in display=1 char msg[] = "Arduino..."; //message to display on the LCD
void setup() { LCD.init(); // initialize LCD }
void loop() { LCD.clear(); LCD.print(msg); delay(1000); LCD.leftScroll(20, 300);// scroll entire display to left } //************************************************************** A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 21
all functions are written in a format LCD.function() where LCD is an object of constructor LCD4Bit
Driving a DC Motor Now we will try to drive a DC motor. The DC motor requires 9V supply. The motor will have two lines. Suppose to drive the motor clockwise we provide 9V to one line and 0V to the other line. If we reverse the line voltages the motor will reverse the running direction. We cannot connect a DC motor directly to Arduino board since the motor require 9V but the Arduino can output only 5V and also the current consumption of motor is high. If the current is allowed to sink from the Arduino board the controller may get damaged. So we use a driver IC instead connecting directly. The driver IC takes the control from Arduino and converts the voltage level to a level required to drive the motor. Now the current for the motor is supplied by the driver IC. In our case we use L293D as driver which is a push pull four channel driver with diode. The supply voltage for this driver is taken from the 9V option of Arduino board. L293D needs an enable signal to activate the Driver module. We permanently tie this pin to supply voltage. Now two lines are required from Arduino to drive the motor using software. Connect these two lines to the input stage to the driver and take the signal from corresponding output pins to drive the motor. Lets write a program to drive a DC motor. It is assumed that a switch is connected to digital pin 2 and the function of this switch is to change the motor state. Initially the motor is OFF. The motor will run in one direction when the switch is pressed. It will change the direction and will finally reach the initial state which is OFF in subsequent switch presses. A switch press produces a HIGH state to Arduino.
# Program 12 //*********Interfacing a DC motor with Arduino ***************** int motorPin_1=12; int motorPin_2=13; int switchPin =2; int inputState=0;
void setup() { pinMode(motorPin_1,OUTPUT); pinMode(motorPin_2,OUTPUT); pinMode(switchPin,INPUT); } void loop() A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 22
{ while(digitalRead(switchPin)==LOW); //waiting switch press while(digitalRead(switchPin)==HIGH); //waiting for de bounce digitalWrite(motorPin_1, HIGH); //run the motor digitalWrite(motorPin_2, LOW); //in one direction
while(digitalRead(switchPin)==LOW); //waiting switch press while(digitalRead(switchPin)==HIGH); //waiting for de bounce digitalWrite(motorPin_1, LOW); //run the motor digitalWrite(motorPin_2, HIGH); //in opposite direction
while(digitalRead(switchPin)==LOW); //waiting switch press while(digitalRead(switchPin)==HIGH); //waiting for de bounce digitalWrite(motorPin_1, LOW); //stop the motor digitalWrite(motorPin_2, LOW);
while(true); // the action is done only once } //**************************************************************
Sensors Light Dependent Resistor (LDR) A photo resistor or Light Dependent Resistor is a resistor whose resistance decreases with increasing incident light intensity. It can also be referred to as a photoconductor. It is made of a high resistance semiconductor. If light falling on the device is of high enough frequency, photons absorbed by the semiconductor give bound electrons enough energy to jump into the conduction band. The resulting free electron (and its hole partner) conduct electricity, thereby lowering resistance. LDR find applications in many electronic items such as camera light meters, clock radios, security alarms, street lights and outdoor clocks. The following program demonstrates how an LDR is interfaced with Arduino. The objective of the program is to control the brightness of an LED using LDR. One PIN of LDR is connected to 5V and the other pin is connected to Arduinos input pin. This pin is connected to a 4.7k resistance which is connected to ground forming a voltage divider. The Arduino measure the change in voltage created by LDR due to change in light intensity.
# Program 13 //********* Interfacing a LDR with Arduino ********************* int ledPin = 9; // LED connected to digital pin 9 int inPin = 2; void setup() A GUIDE TO ARDUINO WORKSHOP
For Training Only Page 23
{ // I/O configuration is needed only for Digital functions // Analog functions automatically set the direction }
The ADC module of Arduino has a resolution of 10 bits this means that there are 1024 levels between 0V and 5V analog signal. Since the register set of Arduino is only 8 bit wide a value 0xFF will saturate the register. Hence to accommodate the 1024 values we divide the read analog signal value by 4 (256*4 =1024). Now the brightness of LED is now depend on the intensity of light detected by LDR
References 1. http://arduino.cc/ 2. Embedded Controller Hardware Design by Ken Arnold, LLH Technology Publishing. 3. Embedded System Design - A Unifide Hardware Software Approach by Frank Vahid and Tony Givargis, Department of Computer Science and Engineering,University of California. 4. Programming Embedded Systems in C and C++by Michel Barr, OReilly. 5. http://www.netrino.com/Embedded-Systems/Glossary. 6. http://en.wikipedia.org/wiki/Embedded_system. 7. http://en.wikipedia.org/wiki/Microprocessor. 8. http://en.wikipedia.org/wiki/Microcontroller. 9. http://en.wikipedia.org/wiki/Programming_language. 10. http://en.wikipedia.org/wiki/Light_Dependent_Resistor 11. http://www.electrofriends.com/articles/lcd/index.html