HRM Review
Beurer PM 200+
Receiver and chest strap provide the Runtastic app with heart rate data
Bonus set: incl. sports armband
Analog signal transmission
Accurate ECG heart rate measurement
Individual training range and alarm
Average and max. heart rate
Calorie consumption in kcal
GPS navigation, speed and route recording with your smartphone
5 training zone suggestions
Date, time, stopwatch
Voice output in DE, EN, FR, IT, ES
Free online account at www.runtastic-com: routes, statistics, social networking, Facebook, Twitter and more
Splash-proof (splashes/perspiration)
Incl. licence code for professional version of Runtastic app
powered by Runtastic see www.runtastic.com
runtastic
Receiver and chest strap provide the Runtastic app with heart rate data
runtastic
Receiver and chest strap provide the Runtastic app with heart rate data
runtastic APP
runtastic APP
For iPhone, Android, Windows Phone 7, Blackberry
Bonus set: incl. sports armband
Bonus set: incl. sports armband
PM 200+
Product name Heart rate measurement with smartphones
Type of measurement ECG-precise heart rate measurement
Transmission Coded or uncoded analog signal transmission
Individual training range + alarm + time in zone yes
Max HR yes
Average HR yes
Calorie consumption (Kcal) yes
Fat burning (g/oz) yes
Time information yes
Date/weekday yes
Wake alarm/stopwatch no/yes
Waterproof yes
Bicycle mounting bracket no
Special equipment Bonus set: incl. sports armband
CE yes
EAN/Item no. 4211125/676.15/5
Beurer PM200+ Reviews - Grimace60 Member since: August 28, 2008
http://www.productreview.com.au/p/beurer-pm200.html
If I had my time again...
3.0
- OK
Grimace60 posted this on Apr 06, 2013
I was in the market for a HRM strap that could be used with smartphone fitness apps and bought the PM200+ from a major electrical retailer.
I had already spent a few dollars on some highly recommended fitness apps that interface with HRM straps unfortunately none of them recognised this particular model with its quirky little box you plug into the headphone jack (note, this is not a Bluetooth device, but uses the box to receive the specific signal from the strap).
The only apps I have found it works with are 'Runtastic' (great if you are a runner...I'm not) and 'Walktastic'; each of which cost $5.50. There was a promo code in the bottom of the box giving you free upgrade to the Runtastic app, unfortunately, I didn't find it until after I had purchased it.
The strap and 'box' came with a handy forearm strap/phone holder as a 'bonus', but at $150, and considerably more than a Bluetooth strap, hardly a 'bonus'.
I contacted Beurer helpline twice, once for a refund on the app purchase, the second for a techinical question and was referred to the User Forum on the Runtastic website. Great customer support!
I have had intermittent connectivity problems with the 'box' working loose from the headphone jack, causing loss of signal. It should be noted that phone cases need to be removed before plugging this in...a further annoyance.
I have found this to be more trouble than its worth and would recommend anyone looking for a HRM that interfaces with smartphones to look at a simple Bluetooth option e.g. Polar H7
.END
Flying Ball Bicycle
.END2
EESTEC Workshop 2012 Day 4. EMG - cs.curs.pub.ro
EESTEC Workshop 2012 Day 4. EMG
http://cs.curs.pub.ro/wiki/pm/eestec/1
http://cs.curs.pub.ro/wiki/pm/eestec/2
http://cs.curs.pub.ro/wiki/pm/eestec/3
http://cs.curs.pub.ro/wiki/pm/eestec/4
olimex ekg board
http://cs.curs.pub.ro/wiki/pm/eestec/3
http://hk.element14.com/olimex/shield-ekg-emg/board-ecg-emg-arduino-shield/dp/2144343
http://www.farnell.com/datasheets/1641097.pdf
Open Source Prosthetic Arm
http://www.youtube.com/watch?v=ZUIqR2JodlY
beurer pm200
Beurer Runtastic PM200+
http://creativecommons.org/licenses/by-nc-sa/3.0/
UNIVERSITATEA "POLITEHNICA" DIN BUCURESTI 布加勒斯特理工大学
http://school.nihaowang.com/55145.html
布加勒斯特理工大学成立于1818年,位于罗马尼亚的布加勒斯特直辖市,是罗马尼亚一所历史悠久的公立大学。
布加勒斯特理工大学的教师都受过专业训练,加之先进的教学方式,为学生提供高品质的教学。
校园十分现代化,学生可以使用各种休闲设施,图书馆,多媒体中心及电脑教室。
学校也提供免费的网络资源给学生使用,非常方便。 布加勒斯特理工大学下设15个院系,可授予学士学位、硕士学位和博士学位,专业设置广泛,开设的主要专业有:航空航天工程、应用电子、应用信息学、应用技术科学、生态系统工程、化学工程、动态系统、电力系统工程、电气系统、能量学和核技术、工程材料加工、食品化学、工业设计、工业经济工程、工业信息学、工业物流、信息工程、信息技术、无机物质技术、机械制造技术、机床和制造系统、材料科学、数理逻辑与应用、机械工程、机电一体化和医学工程等。
Embedded Design Conference - EESTEC Workshop
Goals
During this workshop, we will teach you the basics of programming microcontrollers using the Arduino platform. We will assume basic knowledge of programming in C, but other than that nothing but interest in discovery of the embedded world!
We will start off by exploring the Arduino platform:
Day 1 will revolve around a “Hello World!” very common in the embedded world: blinking an LED. We will explore the platform at our disposal and find out how to program it using the C language.
In Day 2 we will start exploring the capabilities of the platform and we will extend its basic functionality by interfacing with other devices (LEDs, switches, LCDs,etc.)
In Day 3 we will introduce our medical application - the EKG
Day 4 will be your “graduation day”. Given what you have learned, you will have to program a medical application similar to the one presented in Day 3.
Lab notes
Day 1. Introduction to microcontrollers
Day 2. Working with Arduino
Day 3. EKG
Day 4. EMG
Day 4. EMG
Day 4 - Graduation
Left-over from yesterday
As some of you have struggled with adjusting the plot to only display lines, we include the code here:
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()[0], 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()
}
float oldHeight;
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 = height - map(inByte, 0, 1023, 0, height);
// draw the line:
stroke(127,34,255);
int xpos_old = xPos - 1;
if (xpos_old < 0)
xpos_old = 0;
line (xpos_old, oldHeight, xPos, inByte);
oldHeight = 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++;
}
}
}
Most problems yesterday were from excessive noise induced by laptop power supplies or, in our case, HDMI cables. Make sure to disconnect your power supply or additional cables if you experience noise with the application (remember, EKG based on only 3 electrodes is prone to a lot of noise)
EMG - Electromyography
Electromyography is used to measure the electrical activity of muscles.
The method of measuring is the same, use the same board with the same electrodes. Connect electrode P as before to your ankle and watch the figure below for the other positions (depending on the muscle you wish to monitor).
Final Exercise
Display the EMG of a muscle of your choice in the “Processing” application
Count the number of exercises (muscle contractions) made by the patient and display them on the LCD
.END
Politehnica University of Bucharest - Wikipedia
http://www.upb.ro/
Established 1864 (1818)
Type Public
Rector Mihnea Costoiu
Academic staff 1,400
Admin. staff 1,300
Students 25,469 (2011-2012)[1]
Undergraduates 16,864
Postgraduates 8,605
Location Bucharest, Romania
Former names School of Bridges and Roads, Mines and Architecture (1864-1867)
School of Bridges, Roads and Mines (1867-1888)
National School for Bridges and Roads (1888-1920)
Polytechnic School of Bucharest(1920-1938)
Politehnica Carol II of Bucharest(1938-1948)
Polytechnic Institute of Bucharest (1948-1992)
Website www.upb.ro
Universitatea Politehnica din Bucureşti is a technical university in Bucharest, Romania. It was founded in 1864, as School of Bridges and Roads, Mines and Architecture (based on the older technical school of Gheorghe Lazăr, from 1818), and it was renamed Polytechnic School in 1920.[2]
University Politehnica of Bucharest is the largest technical university in Romania. Its traditions are connected to the founding of the first higher technical school in Wallachia, in 1818, by Gheorghe Lazăr. Born in Avrig, Transylvania, Gheorghe Lazăr studied in Sibiu, Cluj and Vienna. In 1817–1818 he endeavored to convince the local noblemen of the need for supporting a modern technical school in Romania.
Thus, on 24 March 1818, by a princely edict of Ioan Caragea, the premises of Saint Sava Abbey were converted into the new school, Şcoala Tehnică Superioară pentru Ingineri Hotarnici ("The Upper School for Surveying Engineers").[3]
Later, in 1832 the school was reorganised, including four cycles, in accordance with the provisions of Organic Regulation. Among other faculties, the one dealing with exact sciences included courses such as applied trigonometry, geodesy, mineralogy, engineering graphics, descriptive geometry, mechanical elements applied to ordinary machines, principles of building roads and bridges, elements of architecture, etc. The graduates were obliged either to work for three years for the state, or to return the grant received. In 1862, the ruler of the United Principalities, Alexandru Ioan Cuza, had established by another Princely Decree a set of rules for the organisation of civil engineers, the hierarchy of engineers or conductors, their salaries, the conditions for admission and promotion, were clearly defined.
An important figure in the "School of Bridges, Roads and Mines" was Gheorghe Duca. As early as 1887, he analysed the content of courses, finding the weaknesses of the school, as well as the best solutions to improve its academic level. In those times, a substantial condition was the severity imposed on the conduct of students, in addition to evaluation. Students obtaining insufficient results, or having an erratic course attendance, were quickly removed from the school. Indeed, at the beginning, the preparatory year had no admission tests. Starting with 1881, an admission test was introduced; the top priority was the quality of candidates, the number of the selected ones being less important.
Gheorghe Duca tried and succeeded to bring the best professors to the “National School of Bridges and Roads”; among these were David Emmanuel (Elementary Mathematics), Spiru Haret (Higher Algebra and Analytical Geometry), C. M. Mironescu (Statistics and Engineering Graphics), Constantin Istrati (Physics), or Anghel Saligny (Bridges and Roads). Moreover, Gheorghe Duca himself was considered the greatest authority in railways at the end of the 19th century. This was perhaps a turning moment, when it was clearly demonstrated that Romania was capable of achieving on its own what had been deemed likely to be obtained only abroad, namely the training of highly qualified science and engineering specialists.
The year 1890 also represented a momentous point, when at the National School of Bridges and Roads a new commission was set up. Its main role was to issue equivalency certificates for the engineering diplomas obtained abroad, thus transforming this national school into a model for evaluating higher technical studies.
Nicolae Vasilescu-Karpen was appointed director of the School in February 1920. As a direct result of his endeavors, the government approved the establishment of Polytechnic Schools in Romania, conceived as higher education institutions, similar to universities, having as their final aim engineering training under the Ministry of Public Works.
The Polytechnic School was set up by transforming the "National School of Bridges and Roads" into the "Polytechnic School of Bucharest". In its initial stage it consisted of four sections:
Civil Engineering;
Mechanics and Electricity;
Mines and Metallurgy;
The Industrial Section.
In this period, in addition to the Polytechnic School, there were Institutes for Engineers within Universities. For instance, the University of Bucharest hosted an institute for electrical engineering, an institute for industrial chemistry and another one for agricultural and food chemistry.
Another important cornerstone was the decree 3799 of 1938 stating that higher education could be provided only by universities, Polytechnic Schools, or Academies for Commercial Studies. As a direct result, the Academy of Higher Agricultural Studies, The Academy of Architecture, The Institute of Industrial Chemistry and Agricultural and Food Chemistry, respectively, were introduced in the framework of "Bucharest Politehnica". The change of name[4] from "Polytechnic School of Bucharest" into "Politehnica Carol II of Bucharest" was accompanied by other changes as well. Thus, Politehnica depended on the Ministry of National Education (instead of the Ministry for Public Works), the former director became Rector of Politehnica, the different sections became Faculties, their presidents in turn, became Deans etc.
Between 1938 and 1948 Politehnica of Bucharest had seven faculties: Civil Engineering, Electro-mechanics, Metallurgy, Industrial Chemistry, Silviculture, Agronomy, and Architecture.
Another important transformation took place in 1948, when several Politehnica or even specialities became independent, or even moved to other cities. Some of the new universities, institutes or faculties had their roots in the old "Politehnica of Bucharest". Thus, the following establishments, were initially faculties or departments at "Politehnica" of Bucharest: Technical University of Civil Engineering of Bucharest; Ion Mincu University of Architecture and Urbanism; University of Agronomic Sciences; Faculty of Forestry - Transilvania University of Brașov; School of Mines - Petroşani; Oil & Gas University of Ploieşti; Faculty for Food Chemistry - University of Galați; Faculty for Textile Industry - Gheorghe Asachi Technical University of Iași.
In 1948-1992, the name of the school was "The Polytechnic Institute of Bucharest". Based on a resolution of the Senate (November 1992), the Polytechnic Institute of Bucharest turned into University Politehnica of Bucharest.Achievements[edit source]
At the 29th annual ACM International Collegiate Programming Contest, held at Shanghai Jiao Tong University, on April 6, 2005, Politehnica was ranked 10th in the world.[5] The university organizes important conferences such as International Conference on Control Systems and Computer Science and symposiums like Interdisciplinary Approaches in Fractal Analysis.
Faculties
The university is structured into faculties. The faculties are distinct academic entities, each having its own admission criteria, largely distinct staff and limited interaction. However, there are a number of commonalities: all the faculties provide only engineering degrees, there is a largely common curricula that is observed in the first year of studies, there are shared teaching facilities and shared student facilities. Currently there are thirteen faculties. :
Faculty of Electrical Engineering
Faculty of Power Engineering
Faculty of Automatic Control and Computer Science
Faculty of Electronics, Telecommunications and Information Technology
Faculty of Mechanical Engineering and Mechatronics
Faculty of Engineering and Management of Technological Systems
Faculty of Biotechnical Systems Engineering
Faculty of Transports
Faculty of Aerospace Engineering
Faculty of Material Science and Engineering
Faculty of Applied Chemistry and Materials Science
Faculty of Engineering Taught in Foreign Languages
Faculty of Applied Sciences
Faculty of Medical Engineering
Faculty of Entrepreneurship, Engineering and Business Management
Technical Colleges
Since 1991, University Politehnica of Bucharest offers short-term (three years) studies equivalent to an Associate Degree within the two Technical Colleges, simply called College Number 1 and College Number 2.
http://cs.curs.pub.ro/wiki/pm/eestec/1
http://cs.curs.pub.ro/wiki/pm/eestec/2
http://cs.curs.pub.ro/wiki/pm/eestec/3
http://cs.curs.pub.ro/wiki/pm/eestec/4
olimex ekg board
http://cs.curs.pub.ro/wiki/pm/eestec/3
http://hk.element14.com/olimex/shield-ekg-emg/board-ecg-emg-arduino-shield/dp/2144343
http://www.farnell.com/datasheets/1641097.pdf
Open Source Prosthetic Arm
http://www.youtube.com/watch?v=ZUIqR2JodlY
beurer pm200
Beurer Runtastic PM200+
http://creativecommons.org/licenses/by-nc-sa/3.0/
UNIVERSITATEA "POLITEHNICA" DIN BUCURESTI 布加勒斯特理工大学
http://school.nihaowang.com/55145.html
布加勒斯特理工大学成立于1818年,位于罗马尼亚的布加勒斯特直辖市,是罗马尼亚一所历史悠久的公立大学。
布加勒斯特理工大学的教师都受过专业训练,加之先进的教学方式,为学生提供高品质的教学。
校园十分现代化,学生可以使用各种休闲设施,图书馆,多媒体中心及电脑教室。
学校也提供免费的网络资源给学生使用,非常方便。 布加勒斯特理工大学下设15个院系,可授予学士学位、硕士学位和博士学位,专业设置广泛,开设的主要专业有:航空航天工程、应用电子、应用信息学、应用技术科学、生态系统工程、化学工程、动态系统、电力系统工程、电气系统、能量学和核技术、工程材料加工、食品化学、工业设计、工业经济工程、工业信息学、工业物流、信息工程、信息技术、无机物质技术、机械制造技术、机床和制造系统、材料科学、数理逻辑与应用、机械工程、机电一体化和医学工程等。
Embedded Design Conference - EESTEC Workshop
Goals
During this workshop, we will teach you the basics of programming microcontrollers using the Arduino platform. We will assume basic knowledge of programming in C, but other than that nothing but interest in discovery of the embedded world!
We will start off by exploring the Arduino platform:
Day 1 will revolve around a “Hello World!” very common in the embedded world: blinking an LED. We will explore the platform at our disposal and find out how to program it using the C language.
In Day 2 we will start exploring the capabilities of the platform and we will extend its basic functionality by interfacing with other devices (LEDs, switches, LCDs,etc.)
In Day 3 we will introduce our medical application - the EKG
Day 4 will be your “graduation day”. Given what you have learned, you will have to program a medical application similar to the one presented in Day 3.
Lab notes
Day 1. Introduction to microcontrollers
Day 2. Working with Arduino
Day 3. EKG
Day 4. EMG
Day 4. EMG
Day 4 - Graduation
Left-over from yesterday
As some of you have struggled with adjusting the plot to only display lines, we include the code here:
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()[0], 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()
}
float oldHeight;
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 = height - map(inByte, 0, 1023, 0, height);
// draw the line:
stroke(127,34,255);
int xpos_old = xPos - 1;
if (xpos_old < 0)
xpos_old = 0;
line (xpos_old, oldHeight, xPos, inByte);
oldHeight = 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++;
}
}
}
Most problems yesterday were from excessive noise induced by laptop power supplies or, in our case, HDMI cables. Make sure to disconnect your power supply or additional cables if you experience noise with the application (remember, EKG based on only 3 electrodes is prone to a lot of noise)
EMG - Electromyography
Electromyography is used to measure the electrical activity of muscles.
The method of measuring is the same, use the same board with the same electrodes. Connect electrode P as before to your ankle and watch the figure below for the other positions (depending on the muscle you wish to monitor).
Final Exercise
Display the EMG of a muscle of your choice in the “Processing” application
Count the number of exercises (muscle contractions) made by the patient and display them on the LCD
.END
Politehnica University of Bucharest - Wikipedia
http://www.upb.ro/
Established 1864 (1818)
Type Public
Rector Mihnea Costoiu
Academic staff 1,400
Admin. staff 1,300
Students 25,469 (2011-2012)[1]
Undergraduates 16,864
Postgraduates 8,605
Location Bucharest, Romania
Former names School of Bridges and Roads, Mines and Architecture (1864-1867)
School of Bridges, Roads and Mines (1867-1888)
National School for Bridges and Roads (1888-1920)
Polytechnic School of Bucharest(1920-1938)
Politehnica Carol II of Bucharest(1938-1948)
Polytechnic Institute of Bucharest (1948-1992)
Website www.upb.ro
Universitatea Politehnica din Bucureşti is a technical university in Bucharest, Romania. It was founded in 1864, as School of Bridges and Roads, Mines and Architecture (based on the older technical school of Gheorghe Lazăr, from 1818), and it was renamed Polytechnic School in 1920.[2]
University Politehnica of Bucharest is the largest technical university in Romania. Its traditions are connected to the founding of the first higher technical school in Wallachia, in 1818, by Gheorghe Lazăr. Born in Avrig, Transylvania, Gheorghe Lazăr studied in Sibiu, Cluj and Vienna. In 1817–1818 he endeavored to convince the local noblemen of the need for supporting a modern technical school in Romania.
Thus, on 24 March 1818, by a princely edict of Ioan Caragea, the premises of Saint Sava Abbey were converted into the new school, Şcoala Tehnică Superioară pentru Ingineri Hotarnici ("The Upper School for Surveying Engineers").[3]
Later, in 1832 the school was reorganised, including four cycles, in accordance with the provisions of Organic Regulation. Among other faculties, the one dealing with exact sciences included courses such as applied trigonometry, geodesy, mineralogy, engineering graphics, descriptive geometry, mechanical elements applied to ordinary machines, principles of building roads and bridges, elements of architecture, etc. The graduates were obliged either to work for three years for the state, or to return the grant received. In 1862, the ruler of the United Principalities, Alexandru Ioan Cuza, had established by another Princely Decree a set of rules for the organisation of civil engineers, the hierarchy of engineers or conductors, their salaries, the conditions for admission and promotion, were clearly defined.
An important figure in the "School of Bridges, Roads and Mines" was Gheorghe Duca. As early as 1887, he analysed the content of courses, finding the weaknesses of the school, as well as the best solutions to improve its academic level. In those times, a substantial condition was the severity imposed on the conduct of students, in addition to evaluation. Students obtaining insufficient results, or having an erratic course attendance, were quickly removed from the school. Indeed, at the beginning, the preparatory year had no admission tests. Starting with 1881, an admission test was introduced; the top priority was the quality of candidates, the number of the selected ones being less important.
Gheorghe Duca tried and succeeded to bring the best professors to the “National School of Bridges and Roads”; among these were David Emmanuel (Elementary Mathematics), Spiru Haret (Higher Algebra and Analytical Geometry), C. M. Mironescu (Statistics and Engineering Graphics), Constantin Istrati (Physics), or Anghel Saligny (Bridges and Roads). Moreover, Gheorghe Duca himself was considered the greatest authority in railways at the end of the 19th century. This was perhaps a turning moment, when it was clearly demonstrated that Romania was capable of achieving on its own what had been deemed likely to be obtained only abroad, namely the training of highly qualified science and engineering specialists.
The year 1890 also represented a momentous point, when at the National School of Bridges and Roads a new commission was set up. Its main role was to issue equivalency certificates for the engineering diplomas obtained abroad, thus transforming this national school into a model for evaluating higher technical studies.
Nicolae Vasilescu-Karpen was appointed director of the School in February 1920. As a direct result of his endeavors, the government approved the establishment of Polytechnic Schools in Romania, conceived as higher education institutions, similar to universities, having as their final aim engineering training under the Ministry of Public Works.
The Polytechnic School was set up by transforming the "National School of Bridges and Roads" into the "Polytechnic School of Bucharest". In its initial stage it consisted of four sections:
Civil Engineering;
Mechanics and Electricity;
Mines and Metallurgy;
The Industrial Section.
In this period, in addition to the Polytechnic School, there were Institutes for Engineers within Universities. For instance, the University of Bucharest hosted an institute for electrical engineering, an institute for industrial chemistry and another one for agricultural and food chemistry.
Another important cornerstone was the decree 3799 of 1938 stating that higher education could be provided only by universities, Polytechnic Schools, or Academies for Commercial Studies. As a direct result, the Academy of Higher Agricultural Studies, The Academy of Architecture, The Institute of Industrial Chemistry and Agricultural and Food Chemistry, respectively, were introduced in the framework of "Bucharest Politehnica". The change of name[4] from "Polytechnic School of Bucharest" into "Politehnica Carol II of Bucharest" was accompanied by other changes as well. Thus, Politehnica depended on the Ministry of National Education (instead of the Ministry for Public Works), the former director became Rector of Politehnica, the different sections became Faculties, their presidents in turn, became Deans etc.
Between 1938 and 1948 Politehnica of Bucharest had seven faculties: Civil Engineering, Electro-mechanics, Metallurgy, Industrial Chemistry, Silviculture, Agronomy, and Architecture.
Another important transformation took place in 1948, when several Politehnica or even specialities became independent, or even moved to other cities. Some of the new universities, institutes or faculties had their roots in the old "Politehnica of Bucharest". Thus, the following establishments, were initially faculties or departments at "Politehnica" of Bucharest: Technical University of Civil Engineering of Bucharest; Ion Mincu University of Architecture and Urbanism; University of Agronomic Sciences; Faculty of Forestry - Transilvania University of Brașov; School of Mines - Petroşani; Oil & Gas University of Ploieşti; Faculty for Food Chemistry - University of Galați; Faculty for Textile Industry - Gheorghe Asachi Technical University of Iași.
In 1948-1992, the name of the school was "The Polytechnic Institute of Bucharest". Based on a resolution of the Senate (November 1992), the Polytechnic Institute of Bucharest turned into University Politehnica of Bucharest.Achievements[edit source]
At the 29th annual ACM International Collegiate Programming Contest, held at Shanghai Jiao Tong University, on April 6, 2005, Politehnica was ranked 10th in the world.[5] The university organizes important conferences such as International Conference on Control Systems and Computer Science and symposiums like Interdisciplinary Approaches in Fractal Analysis.
Faculties
The university is structured into faculties. The faculties are distinct academic entities, each having its own admission criteria, largely distinct staff and limited interaction. However, there are a number of commonalities: all the faculties provide only engineering degrees, there is a largely common curricula that is observed in the first year of studies, there are shared teaching facilities and shared student facilities. Currently there are thirteen faculties. :
Faculty of Electrical Engineering
Faculty of Power Engineering
Faculty of Automatic Control and Computer Science
Faculty of Electronics, Telecommunications and Information Technology
Faculty of Mechanical Engineering and Mechatronics
Faculty of Engineering and Management of Technological Systems
Faculty of Biotechnical Systems Engineering
Faculty of Transports
Faculty of Aerospace Engineering
Faculty of Material Science and Engineering
Faculty of Applied Chemistry and Materials Science
Faculty of Engineering Taught in Foreign Languages
Faculty of Applied Sciences
Faculty of Medical Engineering
Faculty of Entrepreneurship, Engineering and Business Management
Technical Colleges
Since 1991, University Politehnica of Bucharest offers short-term (three years) studies equivalent to an Associate Degree within the two Technical Colleges, simply called College Number 1 and College Number 2.
.END
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
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