Olimex EKG board project

Olimex EKG Board

http://hk.element14.com/olimex/shield-ekg-emg/board-ecg-emg-arduino-shield/dp/2144343


http://www.farnell.com/datasheets/1641097.pdf


*** Olimex EKG Board project ***

Day 3. The EKG Left-over from yesterday

http://cs.curs.pub.ro/wiki/pm/eestec/3

Make sure you have made the exercise consisting of plotting sensor data

Connect different sensors to the Arduino board! (you have a trimmer/light sensor available!)

Display text on an LCD

Objectives

Discover what EKG is and its significance as a medical application

Introduce the SHIELD-EKG-EMG board from Olimex

Learn how to do basic Digital Signal Processing

Signals

So far we've examined analog values, voltages measured at pins A0-A7 of the microcontroller. If we measure multiple times the same voltage we obtain a range

of values called a “signal”. A signal contains information about the variation in time of the measured quantity. We should take a very short look at what we

can do with signals:

* Amplification: Taking a “small” signal, we can “enlarge”. This is akin to multiplication, since each individual value is multiplied by a factor, also

called gain. But what if the signal is noisy? The noise is amplified as well!

EKG

An Electrocardiogram is a method of measuring the electrical activity of the heart over a period of time, by attaching electrodes to the surface of the skin

and measuring electric potential between them. The EKG abbreviation comes from the German term elektrokardiogramm, denoting this method. EKGs are used to

determine regularity of heartbeats and damage to the heart. It is a quick, non-invasive method of monitoring heart activity of a patient.

The phenomenon that enables this method is the depolarization of the heart muscle during each heartbeat. Normally each muscle cell has a negative charge on

its surface, but this is increased at contraction. During a heartbeat, the heart goes through a process of gradually contracting heart chambers, and this is

seen externally as variations of voltage between electrodes placed on either side of the heart.

Electrodes

Usually more than two electrodes are used: Each pair of electrodes would form a *lead*, that is, a voltage difference that can be represented on a display

or on paper as a signal and can be investigated. Common EKG systems can be single-lead, 3-lead, 5-lead or 12-lead. Electrodes forming these pairs have

standardized positions and labels, as in the following table (ommited some) and figure:

Electrode label placement

RA Right arm

LA Left arm

RL Right leg, lateral calf muscle

LL Left leg, same location as right leg

V1 4th intercostal space (between 4th and 5th rib, right side

V2 same as V1, but left side

For our experiment we will use a single-lead system, in which we use the left leg (LL) as reference and display Lead I (LA - RA). On our electrodes, LA and

RA are written as L and R and LL appears as P.

EKG Signal

The EKG Signal appears as in the following figure. The main features you will be able to distinguish on our boards are the three segments: The P-Wave, The

QRS complex and the T-wave. Of special interest is the QRS-complex because it is easy to detect in software and the time between these features in adjacent

cycles gives us the pulse (which we will measure in bpm).

The board

The EKG extension board from Olimex offers very good measurement for an EKG, since it has an amplification chain: A succession of amplification stages

(enlarging the signal) and differential inputs (it actually measures the difference between two signals, given a reference - in our case it measures LL -

LR, with P as reference). As a user of this board all you need to know is that you can connect the output of the measurement to 1 in 6 possible channels (by

default, the measurement is sent to ADC channel 1).

The application

1st exercise - Basic Display of EKG

Our first objective is to display the EKG data as in the image below:

To do this you need to use the “Processing” sketch from day2 and the “Analog Input” sketch from the Arduino and modify the accordingly:

Make the “Processing” application display a line graph instead of a bar graph (as illustrated above)

Hint You need to retain one past value

Modify the “Analog Input” sketch to send from the correct ADC channel

To test this you must connect all three electrodes in their designated positions:

L on the left arm, interior part of the wrist

R on the right arm, same position as L

P on the left leg, interior part of calf muscle

The subject/patient must stay still, it should work while sitting on a chair, as relaxed as possible, but for best results the patient should lie down. The

difference between this system and medical-grade equipment is the number of electrodes and their positioning and contact surface with the skin.

2nd exercise - Detecting peaks

Our second objective is to try to detect the QRS-complex on the EKG curve. You will display a heart symbol on the LCD 200 ms after such a peak, then turning

it off.

You will have to:

Connect the LCD extension board on top of the EKG extension

Detect the QRS pulse (perhaps using thresholds?)

Display either a ♥ or a ' ' (space) (Why?)

A custom character (such as the ♥ symbol), is defined by a vector of integers:

 byte heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000
};

This is then inserted into the LCD's memory during the execution of the setup function:

lcd.createChar(0, heart);

createChar puts a new character into memory from the array of integers (heart in this example) to a certain position (here '0'). To write a ♥, use:

 lcd.write((uint8_t)0); // 0 was the index of the heart symbol that we put in createChar

 Are the measurements evenly spaced? How much time passes from one measurement to another?

3rd exercise - Spacing measurements evenly

Using delay in the previous exercise means that the time between two measurements is delay_interval + how long it takes to run the code. In Day 1 we

explained at the very end a method for not using delay: using the millis() function. Transform your sketch to use this instead of delay.

 How much time passes between measurements now? Why is this important?

4th exercise - Calculating and displaying pulse

Now that measurements are evenly spaced we can calculate our pulse using the time between two QRS peaks.

 What happens on the LCD if you print a number on two digits and then a number on one digit on a future iteration?

Text is overwritten so there will be trailing digits remaining on the LCD screen. The following code is meant to first erase the previous number and then

write the new value

lcd.setCursor(10,1);

lcd.print("    ");

lcd.setCursor(10,1);

lcd.print(pulse);

5th exercise - Averaging the pulse on-the-go

The following formula is used when we want to average values on-the-go, without retaining all elements in an array (retaining at each step only the average

and the number of elements).

Using lcd.setCursor, display on the right side of the LCD the average pulse of the patient.

// *************************************************************************

Day 1. Introduction to microcontrollers

http://cs.curs.pub.ro/wiki/pm/eestec/1

Objectives

The basics of what a microcontroller is/does

What is Arduino Uno?

How to blink an LED

1. What is a microcontroller?

A microcontroller (sometimes abbreviated µC, uC or MCU) is a small computer on a single integrated circuit containing a processor core, memory, and

programmable input/output peripherals. Program memory in the form of NOR flash or OTP ROM is also often included on chip, as well as a typically small

amount of RAM. Microcontrollers are designed for embedded applications, in contrast to the microprocessors used in personal computers or other general

purpose applications. Because of a large amount of peripherals integration and a low production cost, a µC operates on low frequencies, usually tens or

hundreds of MHz. However, microcontrollers are suitable for a wide range of applications, being used both in industrial environments and in consumers goods.

Unlike a microprocessor, a µC is used in situations where a single main functionality is required, this functionality being implemented in the program that

it runs.

The most common structure of a µC is:

central processing unit(µP core), with an 8, 16, 32 or 64 bit architecture

volatile (RAM) or non-volatile (FLASH or EEPROM) memory for the data and program

digital I/O ports

serial interfaces (RS232, SPI, I2C, CAN, RS485)

timers, PWM generators or watchdog

ADCs (Analog to Digital Converters)

support for programming and debugging

Some microcontrollers are based on a Harvard architecture, which means there is a physical separation of the storage and signal pathways for instructions

and data. Therefore, the instructions are stored in a different memory than the data, and they can have a different length than the registers and memory. We

take as an example the AVR Family from Atmel. Here, the instructions are 16-bit length, while the internal registers are 8-bit length.

2. AVR Family from Atmel

The AVR is a modified Harvard architecture 8-bit RISC (Reduced Instruction Set Computing) single chip microcontroller which was developed by Atmel in 1996.

The main AVR architecture was created by two students from the Norwegian Institute of Technology, Alf-Egil Bogen and Vegard Wollan. This architecture was

one of the first to use on-chip flash memory for program storage, as opposed to one-time programmable ROM, ERPOM or EEPROM used by the other MCU families at

that time.

AVR Family offers four main categories:

1. tinyAVR

1-8 kB program storage

8 to 32 pins socket

limited set of peripherals

2. megaAVR

4-256 kB program storage

28 to 100 pins socket

extended instruction set (for multiplication and indirect addressing)

extended set of peripherals

3. XMEGA

16-256 kB program storage

44 to 100 pins socket

high performance interfaces, such as DMA, “Event System”, and support for cryptography
extended set of peripherals

4. Application specific AVR

megaAVR with special functions, such as LCD and USB controllers, CAN etc.

FPSLIC (Field Programmable System Level Integrated Circuit), an AVR core along with a FPGA (Field Programmable Gate Array)

Flash, EEPROM and SRAM memories are integrated in the same core, removing the need for external memory. The program consists of 16-bit length instructions,

which are stored in the Flash memory. The size of the program memory is indicated by the component's name. As an example, ATmega128 has a 128kb of Flash

memory. The addressing space consists of 32 general 8bit registers, I/O registers and the SRAM memory.

AVR uCs have a two-level execution pipeline, allowing the next instruction to be brought from memory(Fetch) while the current one is in execution(Exec).

Most instructions are executed in a single cycle, resulting in a 1MIPS/MHz throughput.

A main advantage in favor of Atmel architecture is the optimization in executing a compiled C code on the AVR microcontrollers.

3. ATmega328

Figure 1. ATmega328 chip

ATmega328 is a microcontroller with a 8bit architecture. Therefore, the registers and the data bus have 8 bits each. However, when you write a program in C,

you can use 32 bits variables in both integer and floating point. The compiler is the one who will translate the instructions that are using 32 bits

variables into assembly code (8 bits).

A short summary of the ATmega328 microcontroller:

Operating Voltage - 1.8 - 5.5V

Clock Speed - 16MHz

Self-Programmable Flash Program Memory - 32KBytes

EEPROM Memory - 1KByte

Internal SRAM - 2KBytes

Write/Erase Cycles - 10.000 Flash/100.000 EEPROM

Some of the internal peripherals of ATmega328:

Two 8-bit Timer/Counters with Separate Prescaler and Compare Mode

One 16-bit Timer/Counter with Separate Prescaler, Compare Mode and Capture Mode

6 PWM Channels

Programmable Serial USART

Master/Slave SPI Serial Interface

Programmable Watchdog Timer with separate on-chip Oscillator

On-chip Analog Comparator

Interrupt and Wake-up on Pin Change

These internal peripherals can be accessed from outside via port pins. These pins are also used as I/O pins for external peripherals.


Figure 2. ATmega328 pinout

4. Arduino

Arduino is a popular open-source single-board microcontroller, descendant of the open-source Wiring platform, designed to make the process of using

electronics in multidisciplinary projects more accessible. The hardware consists of a simple open hardware design for the Arduino board with an ATmel AVR

processor and on-board I/O support. The software consists of a standard programming language compiler and the bootloader that runs on the board.

We will use in this workshop an Arduino Uno board, as shown in Figures 3a and 3b.

Figure 3a. Arduino Uno Front

Figure 3b. Arduino Uno Back

The Arduino Uno is a microcontroller board based on the ATmega328. It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog

inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the

microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started.

A short summary of the Arduino Uno board:

Microcontroller - ATmega328

Operating Voltage - 5V

Input Voltage(recommended) - 7-12V

Input Voltage(limits) - 6-20V

Digital I/O Pins - 14(of which 6 provide PWM output)

Analog Input Pins - 6

DC Current per I/O Pin - 40mA

DC Current for 3.3V Pin - 50mA

Flash Memory - 32 KB(ATmega328) of which 0.5 KB used by bootloader

SRAM - 2 KB(ATmega328)

EEPROM - 1 KB(ATmega328)

Clock Speed - 16 MHz

Power

The Arduino Uno can be powered via the USB connection or with an external power supply. The power source is selected automatically.

External (non-USB) power can come either from an AC-to-DC adapter (wall-wart) or battery. The adapter can be connected by plugging a 2.1mm center-positive

plug into the board's power jack. Leads from a battery can be inserted in the Gnd and Vin pin headers of the POWER connector.

The board can operate on an external supply of 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the

board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.

The power pins are as follows:

VIN. The input voltage to the Arduino board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power

source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin.

5V.This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB

connector (5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't

advise it.

3V3. A 3.3 volt supply generated by the on-board regulator. Maximum current draw is 50 mA.
GND. Ground pins.
Input and Output

Each of the 14 digital pins on the Uno can be used as an input or output, and the available API provides functions to access them: pinMode(), digitalWrite

(), and digitalRead(). They operate at 5 volts. Each pin can provide or receive a maximum of 40 mA and has an internal pull-up resistor1) (disconnected by

default) of 20-50 kOhms. In addition, some pins have specialized functions:

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data. These pins are connected to the corresponding pins of the ATmega8U2 USB-

to-TTL Serial chip.

External Interrupts: 2 and 3. These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value.

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). These pins support SPI communication using the SPI library.

LED: 13. There is a built-in LED connected to digital pin 13. When the pin is HIGH value, the LED is on, when the pin is LOW, it's off.

The Uno has 6 analog inputs, labeled A0 through A5, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from

ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function. Additionally, some

pins have specialized functionality:

TWI: A4 or SDA pin and A5 or SCL pin. Support TWI communication using the Wire library.
There are a couple of other pins on the board:

AREF: Reference voltage for the analog inputs. Used with analogReference().
Reset: Bring this line LOW to reset the microcontroller. Typically used to add a reset button to shields which block the one on the board.

Communication

The Arduino Uno has a number of facilities for communicating with a computer, another Arduino, or other microcontrollers. The ATmega328 provides UART TTL

(5V) serial communication, which is available on digital pins 0 (RX) and 1 (TX). An ATmega16U2 on the board channels this serial communication over USB and

appears as a virtual com port to software on the computer. The '16U2 firmware uses the standard USB COM drivers, and no external driver is needed. However,

on Windows, a .inf file is required. The Arduino software includes a serial monitor which allows simple textual 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

serial communication on pins 0 and 1).

The SoftwareSerial library allows for serial communication on any of the Uno's digital pins.

The ATmega328 also supports I2C (TWI) and SPI communication. The Arduino software includes a Wire library to simplify use of the I2C bus. For SPI

communication, use the SPI library.

Getting started with Arduino

It's time to plug your Arduino in and power it up. The most common way to do this is to plug one end of the USB cable into the Arduino and the other end

into a computer. The computer will then power the Arduino. Make sure your cable is an A-B cable. One end should be thin, rectangular. The other end should

be square.

Figure 4. USB cable

Plug the square end into the Arduino and the thin end into your computer. You should get a small green light on the right side of the board and a few

blinking orange lights, on the left side, as shown here.

Figure 4. How to connect the Arduino to the computer

The Arduino Uno can be programmed with the Arduino software2). Download the apropriate file for your OS:

Windows

Mac OS X

Linux: (32 bit), (64 bit)

Extract the package onto your computer. To open the workspace double click arduino.exe.

Figure 5. Arduino software folder

To install the drivers for the Arduino Uno board you must plug in your board and wait for Windows to begin it's driver installation process. After a few

moments, the process will fail, despite its best efforts. Then, click on the Start Menu, and open up the Control Panel. While in the Control Panel, navigate

to System and Security. Next, click on System. Once the System window is up, open the Device Manager (for Windows XP: in the Control Panel click System,

then navigate to the Hardware tab and click Device Manager). Look under Ports (COM & LPT). You should see an open port named Arduino UNO (COMxx). Right

click on the Arduino UNO (COmxx) port and choose the “Update Driver Software” option. Next, choose the Browse my computer for Driver software option.

Finally, navigate to and select the Uno's driver file, named ArduinoUNO.inf, located in the Drivers folder of the Arduino Software download (not the “FTDI

USB Drivers” sub-directory). Windows will finish up the driver installation from there.

Programming

The ATmega328 on the Arduino Uno comes preburned with a bootloader that allows you to upload new code to it without the use of an external hardware

programmer. It communicates using the original STK500 protocol.

Open the workspace by navigating to the Arduino software folder and double clicking arduino.exe.

Figure 6. Arduino workspace

Now you need to select the correct board. Go to the Tools menu and from the Board dropdown menu select Arduino Uno.

Figure 7. Board selection

Next, you need to configure the Serial Port (also known as the COM Port). Look in Device Manager (Control Panel → System → Device Manager), in the Ports

(COM & LPT) section, to see which port it is. On a PC it will probably be something like COM3 or COM4. On a Mac it will be something like tty.usbserial-

xxxxx. Select that port from Tools menu, Serial Port dropdown.

Figure 8a. Port selection - Windows

Figure 8b. Port selection - Mac

And now it's time to start coding!

Example Code - Output - LED blinking

/*
 * Blink
 *
 * The basic Arduino example.  Turns on an LED on for one second,
 * then off for one second, and so on...  We use pin 13 because,
 * depending on your Arduino board, it has either a built-in LED
 * or a built-in resistor so that you need only an LED.
 *
 * http://www.arduino.cc/en/Tutorial/Blink
 */

int ledPin = 13;                // LED connected to digital pin 13

void setup()                    // run once, when the sketch starts
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()                     // run over and over again
{
  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
}

Lets take a closer look at the functions used.

int ledPin = 13 : declares a variable named ledPin of type int (integer) and assigns the value 13 to it. This variable will be used to describe the pin on

the board where the LED in connected.

void setup() : the setup() function is called when a sketch starts. Use it to initialize variables, pin modes, start using libraries, etc. The setup

function will only run once, after each power-up or reset of the Arduino board.

pinMode(pin, mode) : configures the specified pin to behave either as an input or an output. See the description of digital pins for details. pin: the

number of the pin whose mode you wish to set; mode: either INPUT or OUTPUT

void loop() : after creating a setup() function, which initializes and sets the initial values, the loop() function does precisely what its name suggests,

and loops consecutively, allowing your program to change and respond. Use it to actively control the Arduino board.

digitalWrite(pin, value) : write a HIGH or a LOW value to a digital pin. If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set

to the corresponding value: 5V (or 3.3V on 3.3V boards) for HIGH, 0V (ground) for LOW. If the pin is configured as an INPUT, writing a HIGH value with

digitalWrite() will enable an internal 20K pullup resistor (see this tutorial on digital pins). Writing LOW will disable the pullup. The pullup resistor is

enough to light an LED dimly, so if LEDs appear to work, but very dimly, this is a likely cause. The remedy is to set the pin to an output with the pinMode

() function. pin: the pin number; value: HIGH or LOW.

NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins because it has an LED and resistor attached to it that's soldered to

the board on most boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7 V instead of the expected 5V because the onboard LED

and series resistor pull the voltage level down, meaning it always returns LOW. If you must use pin 13 as a digital input, use an external pull down

resistor.

delay(ms) : pauses the program for the amount of time (in miliseconds) specified as parameter. (There are 1000 milliseconds in a second). ms: the number of

milliseconds to pause (unsigned long).

Connecting LEDs on other pins.

Connect the red LED on digital pin number 6, like in the picture below:

Exercise 1: Rewrite your code to make this LED blink.

Blinking the LED without using delay()

Sometimes you need to do two things at once. For example you might want to blink an LED (or some other time-sensitive function) while reading a button press

or other input. In this case, you can't use delay(), or you'd stop everything else the program while the LED blinked. The program might miss the button

press if it happens during the delay(). This sketch demonstrates how to blink the LED without using delay(). It keeps track of the last time the Arduino

turned the LED on or off. Then, each time through loop(), it checks if a long enough interval has passed. If it has, it toggles the LED on or off.

The code below uses the millis() function, a command that returns the number of milliseconds since the Arduino board started running its current program, to

blink an LED.

/* Blink without Delay

 Turns on and off a light emitting diode(LED) connected to a digital
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.

 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.


 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

 */

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);    
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}
For more info go to http://arduino.cc/en/Reference/HomePage

1) http://www.madsciencenotebook.com/node/4

2) http://arduino.cc/en/Main/Software





Day 2. Working with Arduino

http://cs.curs.pub.ro/wiki/pm/eestec/2

Objectives

Today's objectives are getting used to the basic functions of your Arduino Uno. The following will be covered:

Serial communication

Digital input

Analog input

Plotting sensor data

Text LCD

1. Serial communication

Used for communication between the Arduino board and a computer or other devices. All Arduino boards have at least one serial port (also known as a UART or

USART): Serial. It communicates on digital pins 0 (RX) and 1 (TX) as well as with the computer via USB. Thus, if you use these functions, you cannot also

use pins 0 and 1 for digital input or output.

You can use the Arduino environment's built-in serial monitor to communicate with an Arduino board. Click the serial monitor button in the toolbar and

select the same baud rate used in the call to begin().

Example Code - Serial communication - Echo

/*
 Echo
 Reads data from serial, when available, and prints the result to the serial monitor

 This example code is in the public domain.
 */
int incomingByte = 0;

void setup() {
  //start serial communication with a baud rate of 9600
  Serial.begin(9600);
}

void loop() {
  if(Serial.available() > 0) {
      //read the incoming byte
      incomingByte = Serial.read();

      //NOTE: the byte you sent from serial monitor is considered of type char
      //the value of the character '0' is 48
      //by subtracting 48 from the value returned by the Serial.read() function you get
      //the actual number you entered in serial monitor
      incomingByte = incomingByte - 48;

      //confirm the byte you just received
      Serial.print("I received ");
      Serial.println(incomingByte);
}

2. Reading Digital Inputs

Pushbuttons or switches connect two points in a circuit when you press them. When the pushbutton is open (unpressed) there is no connection between the two

legs of the pushbutton, so the pin is connected to ground (through the pull-down resistor) and reads as LOW, or 0. When the button is closed (pressed), it

makes a connection between its two legs, connecting the pin to 5 volts, so that the pin reads as HIGH, or 1.

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 doesn't have a

solid connection to voltage or ground, and it will randomly return either HIGH or LOW. That's why you need a pull-up resistor in the circuit. This can be

done by attaching a resistor (usually 10K) between the floating pin of the pushbutton and 5V. It can also be done internally by enabling an integrated

pull-up resistor in software for each pin we want to use as input.

Connect the pushbutton in your kit to digital pin 2, like in the picture below:

In the program below, the very first thing that you do will in the setup function is to begin serial communications, at 9600 bits of data per second,

between your Arduino and your computer with the line:

Serial.begin(9600);

Next, initialize digital pin 2, the pin that will read the output from your button, as an input:

pinMode(2,INPUT);

And we enable the internal pull-up resistor for pin 2, in order to read 5V when the button is not pressed. This is done by writing a digital “1” on a pin

that was declared as an input:

digitalWrite(pushButton, HIGH);

Now that your setup has been completed, move into the main loop of your code. When your button is pressed, 5 volts will freely flow through your circuit,

and when it is not pressed, the input pin will be connected to ground through the 10-kilohm resistor. This is a digital input, meaning that the switch can

only be in either an on state (seen by your Arduino as a “1”, or HIGH) or an off state (seen by your Arduino as a “0”, or LOW), with nothing in between.

The first thing you need to do in the main loop of your program is to establish a variable to hold the information coming in from your switch. Since the

information coming in from the switch will be either a “1” or a “0”, you can use an int datatype. Call this variable sensorValue, and set it to equal

whatever is being read on digital pin 2. You can accomplish all this with just one line of code:

int sensorValue = digitalRead(2);

Once the Arduino has read the input, make it print this information back to the computer as a decimal (DEC) value. You can do this with the command

Serial.println() in our last line of code:

Serial.println(sensorValue, DEC);

Now, when you open your Serial Monitor in the Arduino environment, you will see a stream of “1”s if your switch is open, or “0”s if your switch is closed.

/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor

 This example code is in the public domain.
 */

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  digitalWrite(pushButton, HIGH);       // turn on pullup resistors
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  Serial.println(buttonState);
}
Adding outputs

Connect the LED in your kit to digital pin 6, like in the picture below:

We want to turn the LED on when we push the button. For this, we need to modify a bit the previous code:

/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor

 This example code is in the public domain.
 */

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;
int led = 6;
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(pushButton, HIGH);       // turn on pullup resistors
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  Serial.println(buttonState);

  if(buttonState==0) digitalWrite(led, HIGH);
  else  digitalWrite(led, LOW);
}
We've declared the LED on pin 6 as output and added a few lines in the loop() statement that check the state of the button and turn the LED on or off

accordingly. Notice the LED is only ON when the button is pushed.

Exercise 1: Modify the code above to light up the LED when the pushbutton is pushed once and switch off when the pushbutton is pressed again. Send the

button and led states as strings on the serial interface.

Exercise 2: Change the code to make the LED light up when the pushbutton is pressed twice and switch off after another two pushes.

Sending data on the serial interface

An if statement allows you to choose between two discrete options, TRUE or FALSE. When there are more than two options, you can use multiple if statements,

or you can use the switch statement. Switch allows you to choose between several discrete options.

This tutorial shows you how to use switch to turn on one of the two LEDs (pins 13 and 6) based on a byte of data received serially. The sketch listens for

serial input, and turns on a different LED for the characters a, b, c, d.

/*
  Switch statement  with serial input

 Demonstrates the use of a switch statement.  The switch
 statement allows you to choose from among a set of discrete values
 of a variable.  It's like a series of if statements.

 To see this sketch in action, open the Serial monitor and send any character.
 The characters a, b, c, d, will turn on or off the two LEDs.  Any other character will turn
 the LEDs off.

 The circuit:
 * 2 LEDs attached to digital pins 13 and 6 through 220-ohm resistors

 created 1 Jul 2009
 by Tom Igoe

This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SwitchCase2
 */

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
   // initialize the LED pins:
      pinMode(13, OUTPUT);
      pinMode(6, OUTPUT);
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
    case 'a':  
      digitalWrite(13, HIGH);
      digitalWrite(6, LOW);
      break;
    case 'b':  
      digitalWrite(13, LOW);
      digitalWrite(6, HIGH);
      break;
    case 'c':  
      digitalWrite(13, HIGH);
      digitalWrite(6, HIGH);
      break;
    case 'd':  
      digitalWrite(13, LOW);
      digitalWrite(6, LOW);
      break;

    default:
      // turn all the LEDs off:
      digitalWrite(13, LOW);
      digitalWrite(6, LOW);
    }
  }
}

Fading LEDs

LEDs can not only be switched on or off, but you can also vary their luminosity. This example demonstrates the use of the analogWrite() function in fading

an LED off and on. AnalogWrite uses pulse width modulation (PWM), turning a digital pin on and off very quickly, to create a fading effect.

After declaring pin 6 to be your ledPin, there is nothing to do in the setup() function of your code.

The analogWrite() function that you will be using in the main loop of your code requires two arguments: One telling the function which pin to write to, and

one indicating what PWM value to write.

In order to fade your LED off and on, gradually increase your PWM value from 0 (all the way off) to 255 (all the way on), and then back to 0 once again to

complete the cycle. In the sketch below, the PWM value is set using a variable called brightness. Each time through the loop, it increases by the value of

the variable fadeAmount.

If brightness is at either extreme of its value (either 0 or 255), then fadeAmount is changed to its negative. In other words, if fadeAmount is 5, then it

is set to -5. If it's 55, then it's set to 5. The next time through the loop, this change causes brightness to change direction as well.

analogWrite() can change the PWM value very fast, so the delay at the end of the sketch controls the speed of the fade. Try changing the value of the delay

and see how it changes the program.

/*
 Fade

 This example shows how to fade an LED on pin 6
 using the analogWrite() function.

 This example code is in the public domain.
 */

int led = 6;           // the pin that the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup()  {
  // declare pin 6 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()  {
  // set the brightness of pin 6:
  analogWrite(led, brightness);  

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }  
  // wait for 30 milliseconds to see the dimming effect  
  delay(30);                          
}
Exercise 3: Using the code above, make the sketch send the brightness values through the serial port as integers from 0 to 255.

Exercise 4: Write a program that reads the LED brightness from the serial port and modifies it accordingly. Input values can range from 0 to 255. Other

values are ignored by the program.

3. Adding Analog Inputs

A pushbutton can only discern two states: on (5 volts) or off (0 volts). But what about all the other values in between? Can we read an analog value from,

say a sensor and process it with our Arduino? This example shows how to read an analog input pin, map the result to a range from 0 to 255, and then use that

result to set the pulsewidth modulation (PWM) of an output pin to dim or brighten an LED.

Leave the LED connected to port 6 and connect the potentiometer in the kit to analog pin 0, like in the picture below:

In the program below, after declaring two pin assignments (analog 0 for your potentiometer and digital 9 for your LED) and two variables, sensorValue and

outputValue, the only thing that you do will in the setup function is to begin serial communication.

Next, in the main loop of the code, sensorValue is assigned to store the raw analog value coming in from the potentiometer. Because the Arduino has an

analogRead resolution of 0-1023, and an analogWrite resolution of only 0-255, this raw data from the potentiometer needs to be scaled before using it to dim

the LED.

In order to scale this value, use a function called map()

outputValue = map(sensorValue, 0, 1023, 0, 255);
outputValue is assigned to equal the scaled value from the potentiometer. map() accepts five arguments: The value to be mapped, the low range and high range

of the raw data, and the low and high values for that data to be scaled too. In this case, the sensor data is mapped down from its original range of 0 to

1023 to 0 to 255.

The newly mapped sensor data is then output to the analogOutPin dimming or brightening the LED as the potentiometer is turned. Finally, both the raw and

scaled sensor values are sent to the Arduino serial window in a steady stream of data.

/*
  Analog input, analog output, serial output

 Reads an analog input pin, maps the result to a range from 0 to 255
 and uses the result to set the pulsewidth modulation (PWM) of an output pin.
 Also prints the results to the serial monitor.

 The circuit:
 * potentiometer connected to analog pin 0.
   Center pin of the potentiometer goes to the analog pin.
   side pins of the potentiometer go to +5V and ground
 * LED connected from digital pin 6 to ground

 created 29 Dec. 2008
 modified 30 Aug 2011
 by Tom Igoe

 This example code is in the public domain.

 */

// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 6; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);          
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);        


  // wait 10 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(10);                  
}
Exercise 5: Add serial output to the code. It should print out sensorValue and outputValue on the serial interface. Convert the input value from the sensor

to volts and print it.

4. Plotting Sensor Data

This example shows you how to send a byte of data from the Arduino to a personal computer and graph the result. This is called serial communication because

the connection appears to both the Arduino and the computer as a serial port, even though it may actually use a USB cable.

You can use the Arduino serial monitor to view the sent data, or it can be read by Processing.

For this exercise you will need to download Processing. You can get it from here: http://processing.org/download/ Simply unzip it into your Arduino folder

and run the .exe in the root folder.

Keep the potentiometer connected to analog port 0 and upload the following code to the Arduino board:

/*
  Graph

 A simple example of communication from the Arduino board to the computer:
 the value of analog input 0 is sent out the serial port.  We call this "serial"
 communication because the connection appears to both the Arduino and the
 computer as a serial port, even though it may actually use
 a USB cable. Bytes are sent one after another (serially) from the Arduino
 to the computer.

 You can use the Arduino serial monitor to view the sent data, or it can
 be read by Processing, PD, Max/MSP, or any other program capable of reading
 data from a serial port.  The Processing code below graphs the data received
 so you can see the value of the analog input changing over time.

 The circuit:
 Any analog input sensor is attached to analog in pin 0.

 created 2006
 by David A. Mellis
 modified 30 Aug 2011
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/Graph
 */

void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
}

void loop() {
  // send the value of analog input 0:
  Serial.println(analogRead(A0));
  // wait a bit for the analog-to-digital converter
  // to stabilize after the last reading:
  delay(10);
}
The code outputs the analog value of pin 0 to the serial port. You can see the raw values on your terminal, or you can plot them usong the following

Processing sketch:

// Graphing sketch


 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return

 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.

 import processing.serial.*;

 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph

 void setup () {
 // set the window size:
 size(400, 300);      

 // List all the available serial ports
 println(Serial.list());
 // I know that the first port in the serial list on my mac
 // is always my  Arduino, so I open Serial.list()[0].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[3], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background:
 background(0);
 }
 void draw () {
 // everything happens in the serialEvent()
 }

 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\n');

 if (inString != null) {
 // trim off any whitespace:
 inString = trim(inString);
 // convert to an int and map to the screen height:
 float inByte = float(inString);
 inByte = map(inByte, 0, 1023, 0, height);

 // draw the line:
 stroke(127,34,255);
 line(xPos, height, xPos, height - inByte);

 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0);
 }
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }

/* Max/MSP v5 patch for this example
 ----------begin_max5_patcher----------
1591.3oc0YszbaaCD9r7uBL5RalQUAO3CvdyS5zVenWZxs5NcfHgjPCIfJIT
RTxj+6AOHkoTDooroUs0AQPR73a+1cwtK3WtZxzEpOwqlB9YveAlL4KWMYh6
Q1GLo99ISKXeJMmU451zTUQAWpmNy+NM+SZ2y+sR1l02JuU9t0hJvFlNcMPy
dOuBv.U5Rgb0LPpRpYBooM3529latArTUVvzZdFPtsXAuDrrTU.f.sBffXxL
vGE50lIHkUVJXq3fRtdaoDvjYfbgjujaFJSCzq4.tLaN.bi1tJefWpqbO0uz
1IjIABoluxrJ1guxh2JfPO2B5zRNyBCLDFcqbwNvuv9fHCb8bvevyyEU2JKT
YhkBSWPAfq2TZ6YhqmuMUo0feUn+rYpY4YtY+cFw3lUJdCMYAapZqzwUHX8S
crjAd+SIOU6UBAwIygy.Q1+HAA1KH6EveWOFQlitUK92ehfal9kFhUxJ3tWc
sgpxadigWExbt1o7Ps5dk3yttivyg20W0VcSmg1G90qtx92rAZbH4ez.ruy1
nhmaDPidE07J+5n2sg6E6oKXxUSmc20o6E3SPRDbrkXnPGUYE.i5nCNB9TxQ
jG.G0kCTZtH88f07Rt0ZMMWUw8VvbKVAaTk6GyoraPdZff7rQTejBN54lgyv
HE0Ft7AvIvvgvIwO23jBdUkYOuSvIFSiNcjFhiSsUBwsUCh1AgfNSBAeNDBZ
DIDqY.f8.YjfjV1HAn9XDTxyNFYatVTkKx3kcK9GraZpI5jv7GOx+Z37Xh82
LSKHIDmDXaESoXRngIZQDKVkpxUkMCyXCQhcCK1z.G457gi3TzMz4RFD515F
G3bIQQwcP3SOF0zlkGhiCBQ1kOHHFFlXaEBQIQnCwv9QF1LxPZ.A4jR5cyQs
vbvHMJsLll01We+rE2LazX6zYmCraRrsPFwKg1ANBZFY.IAihr8Ox.aH0oAL
hB8nQVw0FSJiZeunOykbT6t3r.NP8.iL+bnwNiXuVMNJH9H9YCm89CFXPBER
bz422p8.O4dg6kRxdyjDqRwMIHTbT3QFLskxJ8tbmQK4tm0XGeZWF7wKKtYY
aTAF.XPNFaaQBinQMJ4QLF0aNHF0JtYuHSxoUZfZY6.UU2ejJTb8lQw8Fo5k
Rv6e2PI+fOM71o2ecY1VgTYdCSxxUqLokuYq9jYJi6lxPgD2NIPePLB0mwbG
YA9Rgxdiu1k5xiLlSU6JVnx6wzg3sYHwTesB8Z5D7RiGZpXyvDNJY.DQX3.H
hvmcUN4bP1yCkhpTle2P37jtBsKrLWcMScEmltOPv22ZfAqQAdKr9HzATQwZ
q18PrUGt6Tst2XMCRUfGuhXs6ccn23YloomMqcTiC5iMGPsHsHRWhWFlaenV
XcqwgCQiGGJzptyS2ZMODBz6fGza0bzmXBj7+DA94bvpR01MffAlueO7HwcI
pWCwmzJdvi9ILgflLAFmyXB6O7ML0YbD26lenmcGxjVsZUN+A6pUK7AtTrPg
M+eRYG0qD9j4I7eEbco8Xh6WcO.or9XDC6UCiewbXHkh6xm5LiPEkzpJDRTu
mEB44Fgz4NCtJvX.SM1vo2SlTCZGAe7GZu6ahdRyzFOhYZ+mbVVSYptBw.K1
tboIkatIA7c1cTKD1u.honLYV04VkluHsXe0szv9pQCE9Ro3jaVB1o15pz2X
zYoBvO5KXCAe0LCYJybE8ZODf4fV8t9qW0zYxq.YJfTosj1bv0xc.SaC0+AV
9V9L.KKyV3SyTcRtmzi6rO.O16USvts4B5xe9EymDvebK0eMfW6+NIsNlE2m
eqRyJ0utRq13+RjmqYKN1e.4d61jjdsauXe3.2p6jgi9hsNIv97CoyJ01xzl
c3ZhUCtSHx3UZgjoEJYqNY+hYs5zZQVFW19L3JDYaTlMLqAAt1G2yXlnFg9a
53L1FJVcv.cOX0dh7mCVGCLce7GFcQwDdH5Ta3nyAS0pQbHxegr+tGIZORgM
RnMj5vGl1Fs16drnk7Tf1XOLgv1n0d2iEsCxR.eQsNOZ4FGF7whofgfI3kES
1kCeOX5L2rifbdu0A9ae2X.V33B1Z+.Bj1FrP5iFrCYCG5EUWSG.hhunHJd.
HJ5hhnng3h9HPj4lud02.1bxGw.
-----------end_max5_patcher-----------

 */
Using the Processing sketch in the code sample above, you'll get a graph of the sensor's value. As you change the value of the analog sensor, you'll get a

graph something like this:

Connecting Sensors to Your Arduino

In your kit you have two simple sensors: a light-dependent resistor, or LDR and a integrated temperature sensor. With them, you can measure ambiental light

intensity and temperature. In order to do this, you must first connect the sensors to your Arduino. You can do that by following the pictures below:

Exercise 6: Connect the sensors to your board on analog inputs 0 and 1 and write a simple sketch that prints over the serial line the instantaneous values

for light intensity and temperature. Plot them on your computer screen using the Processing sketch from the previous example.

Exercise 7: Write a sketch that turns on the LED connected to digital output 6 when temperature or luminosity goes over a predetermined threshold.

5. Diplaying stuff on a text LCD

The LiquidCrystal library allows you to control LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you

can usually tell them by the 16-pin interface.

This example sketch prints “Hello World!” to the LCD and shows the time in seconds since the Arduino was reset.

The LCDs have a parallel interface, meaning that the microcontroller has to manipulate several interface pins at once to control the display. The interface

consists of the following pins:

A register select (RS) pin that controls where in the LCD's memory you're writing data to. You can select either the data register, which holds what goes on

the screen, or an instruction register, which is where the LCD's controller looks for instructions on what to do next.

A Read/Write (R/W) pin that selects reading mode or writing mode

An Enable pin that enables writing to the registers

8 data pins (D0 -D7). The states of these pins (high or low) are the bits that you're writing to a register when you write, or the values you're reading

when you read.

There's also a display constrast pin (Vo), power supply pins (+5V and Gnd) and LED Backlight (Bklt+ and BKlt-) pins that you can use to power the LCD,

control the display contrast, and turn on and off the LED backlight, respectively.

The process of controlling the display involves putting the data that form the image of what you want to display into the data registers, then putting

instructions in the instruction register. The LiquidCrystal Library simplifies this for you so you don't need to know the low-level instructions.

The Hitachi-compatible LCDs can be controlled in two modes: 4-bit or 8-bit. The 4-bit mode requires seven I/O pins from the Arduino, while the 8-bit mode

requires 11 pins. For displaying text on the screen, you can do most everything in 4-bit mode, so example shows how to control a 2×16 LCD in 4-bit mode.

To wire your LED screen to your Arduino, connect the following pins:

  LCD RS pin to digital pin 7
  LCD Enable pin to digital pin 6
  LCD D4 pin to digital pin 5
  LCD D5 pin to digital pin 4
  LCD D6 pin to digital pin 3
  LCD D7 pin to digital pin 2

Additionally, wire a 10K pot to +5V and GND, with it's wiper (output) to LCD screens VO pin (pin3).

/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}

.END*** Olimex EKG Board project ***

Day 3. The EKG Left-over from yesterday

http://cs.curs.pub.ro/wiki/pm/eestec/3

Make sure you have made the exercise consisting of plotting sensor data

Connect different sensors to the Arduino board! (you have a trimmer/light sensor available!)

Display text on an LCD

Objectives

Discover what EKG is and its significance as a medical application

Introduce the SHIELD-EKG-EMG board from Olimex

Learn how to do basic Digital Signal Processing

Signals

So far we've examined analog values, voltages measured at pins A0-A7 of the microcontroller. If we measure multiple times the same voltage we obtain a range

of values called a “signal”. A signal contains information about the variation in time of the measured quantity. We should take a very short look at what we

can do with signals:

* Amplification: Taking a “small” signal, we can “enlarge”. This is akin to multiplication, since each individual value is multiplied by a factor, also

called gain. But what if the signal is noisy? The noise is amplified as well!

EKG

An Electrocardiogram is a method of measuring the electrical activity of the heart over a period of time, by attaching electrodes to the surface of the skin

and measuring electric potential between them. The EKG abbreviation comes from the German term elektrokardiogramm, denoting this method. EKGs are used to

determine regularity of heartbeats and damage to the heart. It is a quick, non-invasive method of monitoring heart activity of a patient.

The phenomenon that enables this method is the depolarization of the heart muscle during each heartbeat. Normally each muscle cell has a negative charge on

its surface, but this is increased at contraction. During a heartbeat, the heart goes through a process of gradually contracting heart chambers, and this is

seen externally as variations of voltage between electrodes placed on either side of the heart.

Electrodes

Usually more than two electrodes are used: Each pair of electrodes would form a *lead*, that is, a voltage difference that can be represented on a display

or on paper as a signal and can be investigated. Common EKG systems can be single-lead, 3-lead, 5-lead or 12-lead. Electrodes forming these pairs have

standardized positions and labels, as in the following table (ommited some) and figure:

Electrode label placement

RA Right arm

LA Left arm

RL Right leg, lateral calf muscle

LL Left leg, same location as right leg

V1 4th intercostal space (between 4th and 5th rib, right side

V2 same as V1, but left side

For our experiment we will use a single-lead system, in which we use the left leg (LL) as reference and display Lead I (LA - RA). On our electrodes, LA and

RA are written as L and R and LL appears as P.

EKG Signal

The EKG Signal appears as in the following figure. The main features you will be able to distinguish on our boards are the three segments: The P-Wave, The

QRS complex and the T-wave. Of special interest is the QRS-complex because it is easy to detect in software and the time between these features in adjacent

cycles gives us the pulse (which we will measure in bpm).

The board

The EKG extension board from Olimex offers very good measurement for an EKG, since it has an amplification chain: A succession of amplification stages

(enlarging the signal) and differential inputs (it actually measures the difference between two signals, given a reference - in our case it measures LL -

LR, with P as reference). As a user of this board all you need to know is that you can connect the output of the measurement to 1 in 6 possible channels (by

default, the measurement is sent to ADC channel 1).

The application

1st exercise - Basic Display of EKG

Our first objective is to display the EKG data as in the image below:

To do this you need to use the “Processing” sketch from day2 and the “Analog Input” sketch from the Arduino and modify the accordingly:

Make the “Processing” application display a line graph instead of a bar graph (as illustrated above)

Hint You need to retain one past value

Modify the “Analog Input” sketch to send from the correct ADC channel

To test this you must connect all three electrodes in their designated positions:

L on the left arm, interior part of the wrist

R on the right arm, same position as L

P on the left leg, interior part of calf muscle

The subject/patient must stay still, it should work while sitting on a chair, as relaxed as possible, but for best results the patient should lie down. The

difference between this system and medical-grade equipment is the number of electrodes and their positioning and contact surface with the skin.

2nd exercise - Detecting peaks

Our second objective is to try to detect the QRS-complex on the EKG curve. You will display a heart symbol on the LCD 200 ms after such a peak, then turning

it off.

You will have to:

Connect the LCD extension board on top of the EKG extension

Detect the QRS pulse (perhaps using thresholds?)

Display either a ♥ or a ' ' (space) (Why?)

A custom character (such as the ♥ symbol), is defined by a vector of integers:

 byte heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000
};

This is then inserted into the LCD's memory during the execution of the setup function:

lcd.createChar(0, heart);

createChar puts a new character into memory from the array of integers (heart in this example) to a certain position (here '0'). To write a ♥, use:

 lcd.write((uint8_t)0); // 0 was the index of the heart symbol that we put in createChar

 Are the measurements evenly spaced? How much time passes from one measurement to another?

3rd exercise - Spacing measurements evenly

Using delay in the previous exercise means that the time between two measurements is delay_interval + how long it takes to run the code. In Day 1 we

explained at the very end a method for not using delay: using the millis() function. Transform your sketch to use this instead of delay.

 How much time passes between measurements now? Why is this important?

4th exercise - Calculating and displaying pulse

Now that measurements are evenly spaced we can calculate our pulse using the time between two QRS peaks.

 What happens on the LCD if you print a number on two digits and then a number on one digit on a future iteration?

Text is overwritten so there will be trailing digits remaining on the LCD screen. The following code is meant to first erase the previous number and then

write the new value

lcd.setCursor(10,1);

lcd.print("    ");

lcd.setCursor(10,1);

lcd.print(pulse);

5th exercise - Averaging the pulse on-the-go

The following formula is used when we want to average values on-the-go, without retaining all elements in an array (retaining at each step only the average

and the number of elements).

Using lcd.setCursor, display on the right side of the LCD the average pulse of the patient.

// *************************************************************************

Day 1. Introduction to microcontrollers

http://cs.curs.pub.ro/wiki/pm/eestec/1

Objectives

The basics of what a microcontroller is/does

What is Arduino Uno?

How to blink an LED

1. What is a microcontroller?

A microcontroller (sometimes abbreviated µC, uC or MCU) is a small computer on a single integrated circuit containing a processor core, memory, and

programmable input/output peripherals. Program memory in the form of NOR flash or OTP ROM is also often included on chip, as well as a typically small

amount of RAM. Microcontrollers are designed for embedded applications, in contrast to the microprocessors used in personal computers or other general

purpose applications. Because of a large amount of peripherals integration and a low production cost, a µC operates on low frequencies, usually tens or

hundreds of MHz. However, microcontrollers are suitable for a wide range of applications, being used both in industrial environments and in consumers goods.

Unlike a microprocessor, a µC is used in situations where a single main functionality is required, this functionality being implemented in the program that

it runs.

The most common structure of a µC is:

central processing unit(µP core), with an 8, 16, 32 or 64 bit architecture

volatile (RAM) or non-volatile (FLASH or EEPROM) memory for the data and program

digital I/O ports

serial interfaces (RS232, SPI, I2C, CAN, RS485)

timers, PWM generators or watchdog

ADCs (Analog to Digital Converters)

support for programming and debugging

Some microcontrollers are based on a Harvard architecture, which means there is a physical separation of the storage and signal pathways for instructions

and data. Therefore, the instructions are stored in a different memory than the data, and they can have a different length than the registers and memory. We

take as an example the AVR Family from Atmel. Here, the instructions are 16-bit length, while the internal registers are 8-bit length.

2. AVR Family from Atmel

The AVR is a modified Harvard architecture 8-bit RISC (Reduced Instruction Set Computing) single chip microcontroller which was developed by Atmel in 1996.

The main AVR architecture was created by two students from the Norwegian Institute of Technology, Alf-Egil Bogen and Vegard Wollan. This architecture was

one of the first to use on-chip flash memory for program storage, as opposed to one-time programmable ROM, ERPOM or EEPROM used by the other MCU families at

that time.

AVR Family offers four main categories:

1. tinyAVR

1-8 kB program storage

8 to 32 pins socket

limited set of peripherals

2. megaAVR

4-256 kB program storage

28 to 100 pins socket

extended instruction set (for multiplication and indirect addressing)

extended set of peripherals

3. XMEGA

16-256 kB program storage

44 to 100 pins socket

high performance interfaces, such as DMA, “Event System”, and support for cryptography
extended set of peripherals

4. Application specific AVR

megaAVR with special functions, such as LCD and USB controllers, CAN etc.

FPSLIC (Field Programmable System Level Integrated Circuit), an AVR core along with a FPGA (Field Programmable Gate Array)

Flash, EEPROM and SRAM memories are integrated in the same core, removing the need for external memory. The program consists of 16-bit length instructions,

which are stored in the Flash memory. The size of the program memory is indicated by the component's name. As an example, ATmega128 has a 128kb of Flash

memory. The addressing space consists of 32 general 8bit registers, I/O registers and the SRAM memory.

AVR uCs have a two-level execution pipeline, allowing the next instruction to be brought from memory(Fetch) while the current one is in execution(Exec).

Most instructions are executed in a single cycle, resulting in a 1MIPS/MHz throughput.

A main advantage in favor of Atmel architecture is the optimization in executing a compiled C code on the AVR microcontrollers.

3. ATmega328

Figure 1. ATmega328 chip

ATmega328 is a microcontroller with a 8bit architecture. Therefore, the registers and the data bus have 8 bits each. However, when you write a program in C,

you can use 32 bits variables in both integer and floating point. The compiler is the one who will translate the instructions that are using 32 bits

variables into assembly code (8 bits).

A short summary of the ATmega328 microcontroller:

Operating Voltage - 1.8 - 5.5V

Clock Speed - 16MHz

Self-Programmable Flash Program Memory - 32KBytes

EEPROM Memory - 1KByte

Internal SRAM - 2KBytes

Write/Erase Cycles - 10.000 Flash/100.000 EEPROM

Some of the internal peripherals of ATmega328:

Two 8-bit Timer/Counters with Separate Prescaler and Compare Mode

One 16-bit Timer/Counter with Separate Prescaler, Compare Mode and Capture Mode

6 PWM Channels

Programmable Serial USART

Master/Slave SPI Serial Interface

Programmable Watchdog Timer with separate on-chip Oscillator

On-chip Analog Comparator

Interrupt and Wake-up on Pin Change

These internal peripherals can be accessed from outside via port pins. These pins are also used as I/O pins for external peripherals.


Figure 2. ATmega328 pinout

4. Arduino

Arduino is a popular open-source single-board microcontroller, descendant of the open-source Wiring platform, designed to make the process of using

electronics in multidisciplinary projects more accessible. The hardware consists of a simple open hardware design for the Arduino board with an ATmel AVR

processor and on-board I/O support. The software consists of a standard programming language compiler and the bootloader that runs on the board.

We will use in this workshop an Arduino Uno board, as shown in Figures 3a and 3b.

Figure 3a. Arduino Uno Front

Figure 3b. Arduino Uno Back

The Arduino Uno is a microcontroller board based on the ATmega328. It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog

inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the

microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started.

A short summary of the Arduino Uno board:

Microcontroller - ATmega328

Operating Voltage - 5V

Input Voltage(recommended) - 7-12V

Input Voltage(limits) - 6-20V

Digital I/O Pins - 14(of which 6 provide PWM output)

Analog Input Pins - 6

DC Current per I/O Pin - 40mA

DC Current for 3.3V Pin - 50mA

Flash Memory - 32 KB(ATmega328) of which 0.5 KB used by bootloader

SRAM - 2 KB(ATmega328)

EEPROM - 1 KB(ATmega328)

Clock Speed - 16 MHz

Power

The Arduino Uno can be powered via the USB connection or with an external power supply. The power source is selected automatically.

External (non-USB) power can come either from an AC-to-DC adapter (wall-wart) or battery. The adapter can be connected by plugging a 2.1mm center-positive

plug into the board's power jack. Leads from a battery can be inserted in the Gnd and Vin pin headers of the POWER connector.

The board can operate on an external supply of 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the

board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.

The power pins are as follows:

VIN. The input voltage to the Arduino board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power

source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin.

5V.This pin outputs a regulated 5V from the regulator on the board. The board can be supplied with power either from the DC power jack (7 - 12V), the USB

connector (5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins bypasses the regulator, and can damage your board. We don't

advise it.

3V3. A 3.3 volt supply generated by the on-board regulator. Maximum current draw is 50 mA.
GND. Ground pins.
Input and Output

Each of the 14 digital pins on the Uno can be used as an input or output, and the available API provides functions to access them: pinMode(), digitalWrite

(), and digitalRead(). They operate at 5 volts. Each pin can provide or receive a maximum of 40 mA and has an internal pull-up resistor1) (disconnected by

default) of 20-50 kOhms. In addition, some pins have specialized functions:

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data. These pins are connected to the corresponding pins of the ATmega8U2 USB-

to-TTL Serial chip.

External Interrupts: 2 and 3. These pins can be configured to trigger an interrupt on a low value, a rising or falling edge, or a change in value.

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with the analogWrite() function.

SPI: 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). These pins support SPI communication using the SPI library.

LED: 13. There is a built-in LED connected to digital pin 13. When the pin is HIGH value, the LED is on, when the pin is LOW, it's off.

The Uno has 6 analog inputs, labeled A0 through A5, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from

ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function. Additionally, some

pins have specialized functionality:

TWI: A4 or SDA pin and A5 or SCL pin. Support TWI communication using the Wire library.
There are a couple of other pins on the board:

AREF: Reference voltage for the analog inputs. Used with analogReference().
Reset: Bring this line LOW to reset the microcontroller. Typically used to add a reset button to shields which block the one on the board.

Communication

The Arduino Uno has a number of facilities for communicating with a computer, another Arduino, or other microcontrollers. The ATmega328 provides UART TTL

(5V) serial communication, which is available on digital pins 0 (RX) and 1 (TX). An ATmega16U2 on the board channels this serial communication over USB and

appears as a virtual com port to software on the computer. The '16U2 firmware uses the standard USB COM drivers, and no external driver is needed. However,

on Windows, a .inf file is required. The Arduino software includes a serial monitor which allows simple textual 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

serial communication on pins 0 and 1).

The SoftwareSerial library allows for serial communication on any of the Uno's digital pins.

The ATmega328 also supports I2C (TWI) and SPI communication. The Arduino software includes a Wire library to simplify use of the I2C bus. For SPI

communication, use the SPI library.

Getting started with Arduino

It's time to plug your Arduino in and power it up. The most common way to do this is to plug one end of the USB cable into the Arduino and the other end

into a computer. The computer will then power the Arduino. Make sure your cable is an A-B cable. One end should be thin, rectangular. The other end should

be square.

Figure 4. USB cable

Plug the square end into the Arduino and the thin end into your computer. You should get a small green light on the right side of the board and a few

blinking orange lights, on the left side, as shown here.

Figure 4. How to connect the Arduino to the computer

The Arduino Uno can be programmed with the Arduino software2). Download the apropriate file for your OS:

Windows

Mac OS X

Linux: (32 bit), (64 bit)

Extract the package onto your computer. To open the workspace double click arduino.exe.

Figure 5. Arduino software folder

To install the drivers for the Arduino Uno board you must plug in your board and wait for Windows to begin it's driver installation process. After a few

moments, the process will fail, despite its best efforts. Then, click on the Start Menu, and open up the Control Panel. While in the Control Panel, navigate

to System and Security. Next, click on System. Once the System window is up, open the Device Manager (for Windows XP: in the Control Panel click System,

then navigate to the Hardware tab and click Device Manager). Look under Ports (COM & LPT). You should see an open port named Arduino UNO (COMxx). Right

click on the Arduino UNO (COmxx) port and choose the “Update Driver Software” option. Next, choose the Browse my computer for Driver software option.

Finally, navigate to and select the Uno's driver file, named ArduinoUNO.inf, located in the Drivers folder of the Arduino Software download (not the “FTDI

USB Drivers” sub-directory). Windows will finish up the driver installation from there.

Programming

The ATmega328 on the Arduino Uno comes preburned with a bootloader that allows you to upload new code to it without the use of an external hardware

programmer. It communicates using the original STK500 protocol.

Open the workspace by navigating to the Arduino software folder and double clicking arduino.exe.

Figure 6. Arduino workspace

Now you need to select the correct board. Go to the Tools menu and from the Board dropdown menu select Arduino Uno.

Figure 7. Board selection

Next, you need to configure the Serial Port (also known as the COM Port). Look in Device Manager (Control Panel → System → Device Manager), in the Ports

(COM & LPT) section, to see which port it is. On a PC it will probably be something like COM3 or COM4. On a Mac it will be something like tty.usbserial-

xxxxx. Select that port from Tools menu, Serial Port dropdown.

Figure 8a. Port selection - Windows

Figure 8b. Port selection - Mac

And now it's time to start coding!

Example Code - Output - LED blinking

/*
 * Blink
 *
 * The basic Arduino example.  Turns on an LED on for one second,
 * then off for one second, and so on...  We use pin 13 because,
 * depending on your Arduino board, it has either a built-in LED
 * or a built-in resistor so that you need only an LED.
 *
 * http://www.arduino.cc/en/Tutorial/Blink
 */

int ledPin = 13;                // LED connected to digital pin 13

void setup()                    // run once, when the sketch starts
{
  pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()                     // run over and over again
{
  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
}

Lets take a closer look at the functions used.

int ledPin = 13 : declares a variable named ledPin of type int (integer) and assigns the value 13 to it. This variable will be used to describe the pin on

the board where the LED in connected.

void setup() : the setup() function is called when a sketch starts. Use it to initialize variables, pin modes, start using libraries, etc. The setup

function will only run once, after each power-up or reset of the Arduino board.

pinMode(pin, mode) : configures the specified pin to behave either as an input or an output. See the description of digital pins for details. pin: the

number of the pin whose mode you wish to set; mode: either INPUT or OUTPUT

void loop() : after creating a setup() function, which initializes and sets the initial values, the loop() function does precisely what its name suggests,

and loops consecutively, allowing your program to change and respond. Use it to actively control the Arduino board.

digitalWrite(pin, value) : write a HIGH or a LOW value to a digital pin. If the pin has been configured as an OUTPUT with pinMode(), its voltage will be set

to the corresponding value: 5V (or 3.3V on 3.3V boards) for HIGH, 0V (ground) for LOW. If the pin is configured as an INPUT, writing a HIGH value with

digitalWrite() will enable an internal 20K pullup resistor (see this tutorial on digital pins). Writing LOW will disable the pullup. The pullup resistor is

enough to light an LED dimly, so if LEDs appear to work, but very dimly, this is a likely cause. The remedy is to set the pin to an output with the pinMode

() function. pin: the pin number; value: HIGH or LOW.

NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins because it has an LED and resistor attached to it that's soldered to

the board on most boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7 V instead of the expected 5V because the onboard LED

and series resistor pull the voltage level down, meaning it always returns LOW. If you must use pin 13 as a digital input, use an external pull down

resistor.

delay(ms) : pauses the program for the amount of time (in miliseconds) specified as parameter. (There are 1000 milliseconds in a second). ms: the number of

milliseconds to pause (unsigned long).

Connecting LEDs on other pins.

Connect the red LED on digital pin number 6, like in the picture below:

Exercise 1: Rewrite your code to make this LED blink.

Blinking the LED without using delay()

Sometimes you need to do two things at once. For example you might want to blink an LED (or some other time-sensitive function) while reading a button press

or other input. In this case, you can't use delay(), or you'd stop everything else the program while the LED blinked. The program might miss the button

press if it happens during the delay(). This sketch demonstrates how to blink the LED without using delay(). It keeps track of the last time the Arduino

turned the LED on or off. Then, each time through loop(), it checks if a long enough interval has passed. If it has, it toggles the LED on or off.

The code below uses the millis() function, a command that returns the number of milliseconds since the Arduino board started running its current program, to

blink an LED.

/* Blink without Delay

 Turns on and off a light emitting diode(LED) connected to a digital
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.

 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.


 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

 */

// constants won't change. Used here to
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);    
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}
For more info go to http://arduino.cc/en/Reference/HomePage

1) http://www.madsciencenotebook.com/node/4

2) http://arduino.cc/en/Main/Software





Day 2. Working with Arduino

http://cs.curs.pub.ro/wiki/pm/eestec/2

Objectives

Today's objectives are getting used to the basic functions of your Arduino Uno. The following will be covered:

Serial communication

Digital input

Analog input

Plotting sensor data

Text LCD

1. Serial communication

Used for communication between the Arduino board and a computer or other devices. All Arduino boards have at least one serial port (also known as a UART or

USART): Serial. It communicates on digital pins 0 (RX) and 1 (TX) as well as with the computer via USB. Thus, if you use these functions, you cannot also

use pins 0 and 1 for digital input or output.

You can use the Arduino environment's built-in serial monitor to communicate with an Arduino board. Click the serial monitor button in the toolbar and

select the same baud rate used in the call to begin().

Example Code - Serial communication - Echo

/*
 Echo
 Reads data from serial, when available, and prints the result to the serial monitor

 This example code is in the public domain.
 */
int incomingByte = 0;

void setup() {
  //start serial communication with a baud rate of 9600
  Serial.begin(9600);
}

void loop() {
  if(Serial.available() > 0) {
      //read the incoming byte
      incomingByte = Serial.read();

      //NOTE: the byte you sent from serial monitor is considered of type char
      //the value of the character '0' is 48
      //by subtracting 48 from the value returned by the Serial.read() function you get
      //the actual number you entered in serial monitor
      incomingByte = incomingByte - 48;

      //confirm the byte you just received
      Serial.print("I received ");
      Serial.println(incomingByte);
}

2. Reading Digital Inputs

Pushbuttons or switches connect two points in a circuit when you press them. When the pushbutton is open (unpressed) there is no connection between the two

legs of the pushbutton, so the pin is connected to ground (through the pull-down resistor) and reads as LOW, or 0. When the button is closed (pressed), it

makes a connection between its two legs, connecting the pin to 5 volts, so that the pin reads as HIGH, or 1.

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 doesn't have a

solid connection to voltage or ground, and it will randomly return either HIGH or LOW. That's why you need a pull-up resistor in the circuit. This can be

done by attaching a resistor (usually 10K) between the floating pin of the pushbutton and 5V. It can also be done internally by enabling an integrated

pull-up resistor in software for each pin we want to use as input.

Connect the pushbutton in your kit to digital pin 2, like in the picture below:

In the program below, the very first thing that you do will in the setup function is to begin serial communications, at 9600 bits of data per second,

between your Arduino and your computer with the line:

Serial.begin(9600);

Next, initialize digital pin 2, the pin that will read the output from your button, as an input:

pinMode(2,INPUT);

And we enable the internal pull-up resistor for pin 2, in order to read 5V when the button is not pressed. This is done by writing a digital “1” on a pin

that was declared as an input:

digitalWrite(pushButton, HIGH);

Now that your setup has been completed, move into the main loop of your code. When your button is pressed, 5 volts will freely flow through your circuit,

and when it is not pressed, the input pin will be connected to ground through the 10-kilohm resistor. This is a digital input, meaning that the switch can

only be in either an on state (seen by your Arduino as a “1”, or HIGH) or an off state (seen by your Arduino as a “0”, or LOW), with nothing in between.

The first thing you need to do in the main loop of your program is to establish a variable to hold the information coming in from your switch. Since the

information coming in from the switch will be either a “1” or a “0”, you can use an int datatype. Call this variable sensorValue, and set it to equal

whatever is being read on digital pin 2. You can accomplish all this with just one line of code:

int sensorValue = digitalRead(2);

Once the Arduino has read the input, make it print this information back to the computer as a decimal (DEC) value. You can do this with the command

Serial.println() in our last line of code:

Serial.println(sensorValue, DEC);

Now, when you open your Serial Monitor in the Arduino environment, you will see a stream of “1”s if your switch is open, or “0”s if your switch is closed.

/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor

 This example code is in the public domain.
 */

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  digitalWrite(pushButton, HIGH);       // turn on pullup resistors
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  Serial.println(buttonState);
}
Adding outputs

Connect the LED in your kit to digital pin 6, like in the picture below:

We want to turn the LED on when we push the button. For this, we need to modify a bit the previous code:

/*
  DigitalReadSerial
 Reads a digital input on pin 2, prints the result to the serial monitor

 This example code is in the public domain.
 */

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;
int led = 6;
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
  pinMode(led, OUTPUT);
  digitalWrite(pushButton, HIGH);       // turn on pullup resistors
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  Serial.println(buttonState);

  if(buttonState==0) digitalWrite(led, HIGH);
  else  digitalWrite(led, LOW);
}
We've declared the LED on pin 6 as output and added a few lines in the loop() statement that check the state of the button and turn the LED on or off

accordingly. Notice the LED is only ON when the button is pushed.

Exercise 1: Modify the code above to light up the LED when the pushbutton is pushed once and switch off when the pushbutton is pressed again. Send the

button and led states as strings on the serial interface.

Exercise 2: Change the code to make the LED light up when the pushbutton is pressed twice and switch off after another two pushes.

Sending data on the serial interface

An if statement allows you to choose between two discrete options, TRUE or FALSE. When there are more than two options, you can use multiple if statements,

or you can use the switch statement. Switch allows you to choose between several discrete options.

This tutorial shows you how to use switch to turn on one of the two LEDs (pins 13 and 6) based on a byte of data received serially. The sketch listens for

serial input, and turns on a different LED for the characters a, b, c, d.

/*
  Switch statement  with serial input

 Demonstrates the use of a switch statement.  The switch
 statement allows you to choose from among a set of discrete values
 of a variable.  It's like a series of if statements.

 To see this sketch in action, open the Serial monitor and send any character.
 The characters a, b, c, d, will turn on or off the two LEDs.  Any other character will turn
 the LEDs off.

 The circuit:
 * 2 LEDs attached to digital pins 13 and 6 through 220-ohm resistors

 created 1 Jul 2009
 by Tom Igoe

This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SwitchCase2
 */

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
   // initialize the LED pins:
      pinMode(13, OUTPUT);
      pinMode(6, OUTPUT);
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
    case 'a':  
      digitalWrite(13, HIGH);
      digitalWrite(6, LOW);
      break;
    case 'b':  
      digitalWrite(13, LOW);
      digitalWrite(6, HIGH);
      break;
    case 'c':  
      digitalWrite(13, HIGH);
      digitalWrite(6, HIGH);
      break;
    case 'd':  
      digitalWrite(13, LOW);
      digitalWrite(6, LOW);
      break;

    default:
      // turn all the LEDs off:
      digitalWrite(13, LOW);
      digitalWrite(6, LOW);
    }
  }
}

Fading LEDs

LEDs can not only be switched on or off, but you can also vary their luminosity. This example demonstrates the use of the analogWrite() function in fading

an LED off and on. AnalogWrite uses pulse width modulation (PWM), turning a digital pin on and off very quickly, to create a fading effect.

After declaring pin 6 to be your ledPin, there is nothing to do in the setup() function of your code.

The analogWrite() function that you will be using in the main loop of your code requires two arguments: One telling the function which pin to write to, and

one indicating what PWM value to write.

In order to fade your LED off and on, gradually increase your PWM value from 0 (all the way off) to 255 (all the way on), and then back to 0 once again to

complete the cycle. In the sketch below, the PWM value is set using a variable called brightness. Each time through the loop, it increases by the value of

the variable fadeAmount.

If brightness is at either extreme of its value (either 0 or 255), then fadeAmount is changed to its negative. In other words, if fadeAmount is 5, then it

is set to -5. If it's 55, then it's set to 5. The next time through the loop, this change causes brightness to change direction as well.

analogWrite() can change the PWM value very fast, so the delay at the end of the sketch controls the speed of the fade. Try changing the value of the delay

and see how it changes the program.

/*
 Fade

 This example shows how to fade an LED on pin 6
 using the analogWrite() function.

 This example code is in the public domain.
 */

int led = 6;           // the pin that the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup()  {
  // declare pin 6 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()  {
  // set the brightness of pin 6:
  analogWrite(led, brightness);  

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }  
  // wait for 30 milliseconds to see the dimming effect  
  delay(30);                          
}
Exercise 3: Using the code above, make the sketch send the brightness values through the serial port as integers from 0 to 255.

Exercise 4: Write a program that reads the LED brightness from the serial port and modifies it accordingly. Input values can range from 0 to 255. Other

values are ignored by the program.

3. Adding Analog Inputs

A pushbutton can only discern two states: on (5 volts) or off (0 volts). But what about all the other values in between? Can we read an analog value from,

say a sensor and process it with our Arduino? This example shows how to read an analog input pin, map the result to a range from 0 to 255, and then use that

result to set the pulsewidth modulation (PWM) of an output pin to dim or brighten an LED.

Leave the LED connected to port 6 and connect the potentiometer in the kit to analog pin 0, like in the picture below:

In the program below, after declaring two pin assignments (analog 0 for your potentiometer and digital 9 for your LED) and two variables, sensorValue and

outputValue, the only thing that you do will in the setup function is to begin serial communication.

Next, in the main loop of the code, sensorValue is assigned to store the raw analog value coming in from the potentiometer. Because the Arduino has an

analogRead resolution of 0-1023, and an analogWrite resolution of only 0-255, this raw data from the potentiometer needs to be scaled before using it to dim

the LED.

In order to scale this value, use a function called map()

outputValue = map(sensorValue, 0, 1023, 0, 255);
outputValue is assigned to equal the scaled value from the potentiometer. map() accepts five arguments: The value to be mapped, the low range and high range

of the raw data, and the low and high values for that data to be scaled too. In this case, the sensor data is mapped down from its original range of 0 to

1023 to 0 to 255.

The newly mapped sensor data is then output to the analogOutPin dimming or brightening the LED as the potentiometer is turned. Finally, both the raw and

scaled sensor values are sent to the Arduino serial window in a steady stream of data.

/*
  Analog input, analog output, serial output

 Reads an analog input pin, maps the result to a range from 0 to 255
 and uses the result to set the pulsewidth modulation (PWM) of an output pin.
 Also prints the results to the serial monitor.

 The circuit:
 * potentiometer connected to analog pin 0.
   Center pin of the potentiometer goes to the analog pin.
   side pins of the potentiometer go to +5V and ground
 * LED connected from digital pin 6 to ground

 created 29 Dec. 2008
 modified 30 Aug 2011
 by Tom Igoe

 This example code is in the public domain.

 */

// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 6; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);          
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);        


  // wait 10 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(10);                  
}
Exercise 5: Add serial output to the code. It should print out sensorValue and outputValue on the serial interface. Convert the input value from the sensor

to volts and print it.

4. Plotting Sensor Data

This example shows you how to send a byte of data from the Arduino to a personal computer and graph the result. This is called serial communication because

the connection appears to both the Arduino and the computer as a serial port, even though it may actually use a USB cable.

You can use the Arduino serial monitor to view the sent data, or it can be read by Processing.

For this exercise you will need to download Processing. You can get it from here: http://processing.org/download/ Simply unzip it into your Arduino folder

and run the .exe in the root folder.

Keep the potentiometer connected to analog port 0 and upload the following code to the Arduino board:

/*
  Graph

 A simple example of communication from the Arduino board to the computer:
 the value of analog input 0 is sent out the serial port.  We call this "serial"
 communication because the connection appears to both the Arduino and the
 computer as a serial port, even though it may actually use
 a USB cable. Bytes are sent one after another (serially) from the Arduino
 to the computer.

 You can use the Arduino serial monitor to view the sent data, or it can
 be read by Processing, PD, Max/MSP, or any other program capable of reading
 data from a serial port.  The Processing code below graphs the data received
 so you can see the value of the analog input changing over time.

 The circuit:
 Any analog input sensor is attached to analog in pin 0.

 created 2006
 by David A. Mellis
 modified 30 Aug 2011
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/Graph
 */

void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
}

void loop() {
  // send the value of analog input 0:
  Serial.println(analogRead(A0));
  // wait a bit for the analog-to-digital converter
  // to stabilize after the last reading:
  delay(10);
}
The code outputs the analog value of pin 0 to the serial port. You can see the raw values on your terminal, or you can plot them usong the following

Processing sketch:

// Graphing sketch


 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return

 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.

 import processing.serial.*;

 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph

 void setup () {
 // set the window size:
 size(400, 300);      

 // List all the available serial ports
 println(Serial.list());
 // I know that the first port in the serial list on my mac
 // is always my  Arduino, so I open Serial.list()[0].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[3], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background:
 background(0);
 }
 void draw () {
 // everything happens in the serialEvent()
 }

 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\n');

 if (inString != null) {
 // trim off any whitespace:
 inString = trim(inString);
 // convert to an int and map to the screen height:
 float inByte = float(inString);
 inByte = map(inByte, 0, 1023, 0, height);

 // draw the line:
 stroke(127,34,255);
 line(xPos, height, xPos, height - inByte);

 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0);
 }
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }

/* Max/MSP v5 patch for this example
 ----------begin_max5_patcher----------
1591.3oc0YszbaaCD9r7uBL5RalQUAO3CvdyS5zVenWZxs5NcfHgjPCIfJIT
RTxj+6AOHkoTDooroUs0AQPR73a+1cwtK3WtZxzEpOwqlB9YveAlL4KWMYh6
Q1GLo99ISKXeJMmU451zTUQAWpmNy+NM+SZ2y+sR1l02JuU9t0hJvFlNcMPy
dOuBv.U5Rgb0LPpRpYBooM3529latArTUVvzZdFPtsXAuDrrTU.f.sBffXxL
vGE50lIHkUVJXq3fRtdaoDvjYfbgjujaFJSCzq4.tLaN.bi1tJefWpqbO0uz
1IjIABoluxrJ1guxh2JfPO2B5zRNyBCLDFcqbwNvuv9fHCb8bvevyyEU2JKT
YhkBSWPAfq2TZ6YhqmuMUo0feUn+rYpY4YtY+cFw3lUJdCMYAapZqzwUHX8S
crjAd+SIOU6UBAwIygy.Q1+HAA1KH6EveWOFQlitUK92ehfal9kFhUxJ3tWc
sgpxadigWExbt1o7Ps5dk3yttivyg20W0VcSmg1G90qtx92rAZbH4ez.ruy1
nhmaDPidE07J+5n2sg6E6oKXxUSmc20o6E3SPRDbrkXnPGUYE.i5nCNB9TxQ
jG.G0kCTZtH88f07Rt0ZMMWUw8VvbKVAaTk6GyoraPdZff7rQTejBN54lgyv
HE0Ft7AvIvvgvIwO23jBdUkYOuSvIFSiNcjFhiSsUBwsUCh1AgfNSBAeNDBZ
DIDqY.f8.YjfjV1HAn9XDTxyNFYatVTkKx3kcK9GraZpI5jv7GOx+Z37Xh82
LSKHIDmDXaESoXRngIZQDKVkpxUkMCyXCQhcCK1z.G457gi3TzMz4RFD515F
G3bIQQwcP3SOF0zlkGhiCBQ1kOHHFFlXaEBQIQnCwv9QF1LxPZ.A4jR5cyQs
vbvHMJsLll01We+rE2LazX6zYmCraRrsPFwKg1ANBZFY.IAihr8Ox.aH0oAL
hB8nQVw0FSJiZeunOykbT6t3r.NP8.iL+bnwNiXuVMNJH9H9YCm89CFXPBER
bz422p8.O4dg6kRxdyjDqRwMIHTbT3QFLskxJ8tbmQK4tm0XGeZWF7wKKtYY
aTAF.XPNFaaQBinQMJ4QLF0aNHF0JtYuHSxoUZfZY6.UU2ejJTb8lQw8Fo5k
Rv6e2PI+fOM71o2ecY1VgTYdCSxxUqLokuYq9jYJi6lxPgD2NIPePLB0mwbG
YA9Rgxdiu1k5xiLlSU6JVnx6wzg3sYHwTesB8Z5D7RiGZpXyvDNJY.DQX3.H
hvmcUN4bP1yCkhpTle2P37jtBsKrLWcMScEmltOPv22ZfAqQAdKr9HzATQwZ
q18PrUGt6Tst2XMCRUfGuhXs6ccn23YloomMqcTiC5iMGPsHsHRWhWFlaenV
XcqwgCQiGGJzptyS2ZMODBz6fGza0bzmXBj7+DA94bvpR01MffAlueO7HwcI
pWCwmzJdvi9ILgflLAFmyXB6O7ML0YbD26lenmcGxjVsZUN+A6pUK7AtTrPg
M+eRYG0qD9j4I7eEbco8Xh6WcO.or9XDC6UCiewbXHkh6xm5LiPEkzpJDRTu
mEB44Fgz4NCtJvX.SM1vo2SlTCZGAe7GZu6ahdRyzFOhYZ+mbVVSYptBw.K1
tboIkatIA7c1cTKD1u.honLYV04VkluHsXe0szv9pQCE9Ro3jaVB1o15pz2X
zYoBvO5KXCAe0LCYJybE8ZODf4fV8t9qW0zYxq.YJfTosj1bv0xc.SaC0+AV
9V9L.KKyV3SyTcRtmzi6rO.O16USvts4B5xe9EymDvebK0eMfW6+NIsNlE2m
eqRyJ0utRq13+RjmqYKN1e.4d61jjdsauXe3.2p6jgi9hsNIv97CoyJ01xzl
c3ZhUCtSHx3UZgjoEJYqNY+hYs5zZQVFW19L3JDYaTlMLqAAt1G2yXlnFg9a
53L1FJVcv.cOX0dh7mCVGCLce7GFcQwDdH5Ta3nyAS0pQbHxegr+tGIZORgM
RnMj5vGl1Fs16drnk7Tf1XOLgv1n0d2iEsCxR.eQsNOZ4FGF7whofgfI3kES
1kCeOX5L2rifbdu0A9ae2X.V33B1Z+.Bj1FrP5iFrCYCG5EUWSG.hhunHJd.
HJ5hhnng3h9HPj4lud02.1bxGw.
-----------end_max5_patcher-----------

 */
Using the Processing sketch in the code sample above, you'll get a graph of the sensor's value. As you change the value of the analog sensor, you'll get a

graph something like this:

Connecting Sensors to Your Arduino

In your kit you have two simple sensors: a light-dependent resistor, or LDR and a integrated temperature sensor. With them, you can measure ambiental light

intensity and temperature. In order to do this, you must first connect the sensors to your Arduino. You can do that by following the pictures below:

Exercise 6: Connect the sensors to your board on analog inputs 0 and 1 and write a simple sketch that prints over the serial line the instantaneous values

for light intensity and temperature. Plot them on your computer screen using the Processing sketch from the previous example.

Exercise 7: Write a sketch that turns on the LED connected to digital output 6 when temperature or luminosity goes over a predetermined threshold.

5. Diplaying stuff on a text LCD

The LiquidCrystal library allows you to control LCD displays that are compatible with the Hitachi HD44780 driver. There are many of them out there, and you

can usually tell them by the 16-pin interface.

This example sketch prints “Hello World!” to the LCD and shows the time in seconds since the Arduino was reset.

The LCDs have a parallel interface, meaning that the microcontroller has to manipulate several interface pins at once to control the display. The interface

consists of the following pins:

A register select (RS) pin that controls where in the LCD's memory you're writing data to. You can select either the data register, which holds what goes on

the screen, or an instruction register, which is where the LCD's controller looks for instructions on what to do next.

A Read/Write (R/W) pin that selects reading mode or writing mode

An Enable pin that enables writing to the registers

8 data pins (D0 -D7). The states of these pins (high or low) are the bits that you're writing to a register when you write, or the values you're reading

when you read.

There's also a display constrast pin (Vo), power supply pins (+5V and Gnd) and LED Backlight (Bklt+ and BKlt-) pins that you can use to power the LCD,

control the display contrast, and turn on and off the LED backlight, respectively.

The process of controlling the display involves putting the data that form the image of what you want to display into the data registers, then putting

instructions in the instruction register. The LiquidCrystal Library simplifies this for you so you don't need to know the low-level instructions.

The Hitachi-compatible LCDs can be controlled in two modes: 4-bit or 8-bit. The 4-bit mode requires seven I/O pins from the Arduino, while the 8-bit mode

requires 11 pins. For displaying text on the screen, you can do most everything in 4-bit mode, so example shows how to control a 2×16 LCD in 4-bit mode.

To wire your LED screen to your Arduino, connect the following pins:

  LCD RS pin to digital pin 7
  LCD Enable pin to digital pin 6
  LCD D4 pin to digital pin 5
  LCD D5 pin to digital pin 4
  LCD D6 pin to digital pin 3
  LCD D7 pin to digital pin 2

Additionally, wire a 10K pot to +5V and GND, with it's wiper (output) to LCD screens VO pin (pin3).

/*
  LiquidCrystal Library - Hello World

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD
 and shows the time.

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/LiquidCrystal
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcd.print(millis()/1000);
}

.END

No comments:

Post a Comment