Arduino VI: Bioinstrumentation (Synthesis Lectures on Digital Circuits & Systems) [1st ed. 2024] 3031471296, 9783031471292


142 112 9MB

English Pages 315 Year 2023

Report DMCA / Copyright

DOWNLOAD PDF FILE

Recommend Papers

Arduino VI: Bioinstrumentation (Synthesis Lectures on Digital Circuits & Systems) [1st ed. 2024]
 3031471296, 9783031471292

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

Synthesis Lectures on Digital Circuits & Systems

Steven F. Barrett

Arduino VI Bioinstrumentation

Synthesis Lectures on Digital Circuits & Systems Series Editor Mitchell A. Thornton, Southern Methodist University, Dallas, USA

This series includes titles of interest to students, professionals, and researchers in the area of design and analysis of digital circuits and systems. Each Lecture is self-contained and focuses on the background information required to understand the subject matter and practical case studies that illustrate applications. The format of a Lecture is structured such that each will be devoted to a specific topic in digital circuits and systems rather than a larger overview of several topics such as that found in a comprehensive handbook. The Lectures cover both well-established areas as well as newly developed or emerging material in digital circuits and systems design and analysis.

Steven F. Barrett

Arduino VI Bioinstrumentation

Steven F. Barrett Department of Electrical Engineering and Computer Science University of Wyoming Laramie, WY, USA

ISSN 1932-3166 ISSN 1932-3174 (electronic) Synthesis Lectures on Digital Circuits & Systems ISBN 978-3-031-47129-2 ISBN 978-3-031-47130-8 (eBook) https://doi.org/10.1007/978-3-031-47130-8 © The Editor(s) (if applicable) and The Author(s), under exclusive license to Springer Nature Switzerland AG 2024 This work is subject to copyright. All rights are solely and exclusively licensed by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. The use of general descriptive names, registered names, trademarks, service marks, etc. in this publication does not imply, even in the absence of a specific statement, that such names are exempt from the relevant protective laws and regulations and therefore free for general use. The publisher, the authors, and the editors are safe to assume that the advice and information in this book are believed to be true and accurate at the date of publication. Neither the publisher nor the authors or the editors give a warranty, expressed or implied, with respect to the material contained herein or for any errors or omissions that may have been made. The publisher remains neutral with regard to jurisdictional claims in published maps and institutional affiliations. This Springer imprint is published by the registered company Springer Nature Switzerland AG The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland Paper in this product is recyclable.

Preface

This book is about the Arduino microcontroller and the Arduino concept. The visionary Arduino team of Massimo Banzi, David Cuartielles, Tom Igoe, Gianluca Martino, and David Mellis launched a new innovation in microcontroller hardware in 2005, the concept of open-source hardware. Their approach was to openly share details of microcontrollerbased hardware design platforms to stimulate the sharing of ideas and promote innovation. This concept has been popular in the software world for many years. Their efforts resulted in a global phenomena of making computing accessible for all. This book, “Arduino VI: Bioinstrumentation,” is an accessible primer on bioinstrumentation for those without a deep instrumentation background. An understanding of basic circuit theory is an appropriate prerequisite for the book.1 The three main goals for the book are: explore accessible Arduino microcontroller programming and interfacing concepts; investigate the source and measurement of biomedical signals; and develop skills to design and implement biomedical instrumentation. Throughout the book electrical safety is emphasized. The book is purposely broad in scope to encompass concepts and applications from bioengineering, biomedical, and biological engineering.2

Approach of the Book The book has been divided into three parts to accomplish the book’s goals. The book follows these three steps:

1 For a thorough review of biomedical circuit theory please see “Bioinstrumentation,” John D.

Enderle, Synthesis Lecture on Biomedical Engineering, 6, Morgan and Claypool Publishers, 2006. 2 ABET is a nonprofit, non-governmental agency globally accrediting programs in applied and natu-

ral science, computing, engineering and engineering technology. Annually ABET publishes general and program-specific engineering criteria. Please see the different program criteria for bioengineering, biomedical, and biological engineering www.abet.org.

v

vi

Preface

1. Part I: Introduction to Arduino platforms, the Arduino integrated development environment (IDE), Arduino subsystems, programming, and interfacing. . Chapter 1. Getting started . Chapter 2. Programming Arduino subsystems . Chapter 3. Power sources and interfacing 2. Part II: Measuring physiological signals . Chapter 4. Amplifiers and filtering . Chapter 5. Biopotentials and electrodes including biomedical signals: electromyogram (EMG), electrocardiogram (ECG), electroencephalogram (EEG) 3. Part III: Developing skills to design and implement medical instrumentation . Chapter 6. Systems design tools and examples . Appendix A: Safety . Appendix B: Programming in C Part I provides an introduction to the Arduino platform, describes how to program a specific platform using the Arduino IDE, and describes how to properly interface input and output devices. Information is provided on three different Arduino platforms: the Arduino UNO R3,3 the ATmega2560, and the wearable Arduino LilyPad. Lessons learned can be easily applied to other Arduino platforms. Part II explores the fundamentals of measuring biomedical signals. The section begins with the fundamentals of signal amplification and filtering using operational amplifiers (op amps), instrumentation amplifiers, and isolation amplifiers for patient safety. Next we explore the origin of biopotentials at the cellular level and how to measure related signals from the surface of the human body using electrodes. We then explore the origins of different types of human-generated biomedical signals and how to measure them. In Part III, we apply material learned in the first two parts to design a bioinstrumentation system. We review the system design process and tools. We also emphasize the fundamentals of patient and equipment safety in system design. We conclude with a series of detailed examples. Throughout the book we provide numerous hardware and software examples. As previously mentioned, a tutorial on biomedical safety concepts is readily available in Appendix A and referenced throughout the book. We recommend reading this appendix first (now) and regularly as you progress through the book. Appendix B provides an introduction to programming in C.4 You will find the programming syntax used in the Arduino IDE is very similar to C. For completeness and independence, this volume contains tutorial information on getting started, microcontroller subsystems, and interface information contained in some of 3 Arduino recently announced the release of the Arduino UNO R4. This new exciting processor

board deserves a book of its own. 4 Additional information on programming in C is available in “Arduino II: Systems,” S. Barrett,

Morgan & Claypool Publishers, Springer, 2020.

Preface

vii

the other volumes in the Arduino series and related works completed for Morgan and Claypool and Springer Nature. Chapter footnotes identify the source of this information contained elsewhere in the series. The book series thus far includes: . . . . . .

Arduino Arduino Arduino Arduino Arduino Arduino

I: Getting Started II: Systems III: Internet of Things IV: DIY Robots—3D Printing, Instrumentation, Control V: AI and Machine Learning VI: Bioinstrumentation

In the rapidly evolving Arduino world, I anticipate other books in the series.

Acknowledgments A number of people have made this book series possible. I would like to thank Massimo Banzi of the Arduino design team for his support and encouragement in writing the first edition of this book: “Arduino Microcontroller: Processing for Everyone!” I would also like to acknowledge Joel Claypool for his publishing expertise and support on a number of writing projects. His vision and expertise in the publishing world has made this book possible. Joel “retired” in September 2022 after 40 plus years of service to the U.S. Navy and the publishing world. On behalf of the multitude of writers you have provided a chance to become published authors, we thank you! I would also like to thank Charles (Chuck) Glaser, Editorial Director at Springer Nature, for his encouragement and support on this project. If you have a good idea for a book, I highly recommend contacting Chuck. He will assist you in converting your idea into a finished, professional book product. I would also like to thank Dharaneeswaran Sundaramurthy and Vidyalakshmi Velmurugan of Total Service Books Production for his expertise in converting the final draft into a finished product. You provide outstanding service. Finally, as most importantly, I would like to thank my wife and best friend of many (almost 50) years, Cindy. Laramie, WY, USA January 2024

Steven F. Barrett

Contents

Part I

Introduction to Arduino, the IDE, Programming, and Interfacing

1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 The Big Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Arduino Quickstart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Quick Start Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Arduino Development Environment Overview . . . . . . . . . . . . . . . 1.3.3 Sketchbook Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.4 Arduino Software, Libraries, and Language References . . . . . . . 1.3.5 Writing an Arduino Sketch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4 Arduino Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 Arduino UNO R3 Processing Board . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6 Arduino UNO R3 Host Processor–the ATmega328 . . . . . . . . . . . . . . . . . . 1.6.1 Arduino UNO R3/ATmega328 Hardware Features . . . . . . . . . . . 1.6.2 ATmega328 Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.3 ATmega328 Port System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.4 ATmega328 Internal Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.7 Arduino UNO R3 Open Source Schematic . . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Arduino Mega 2560 R3 Processing Board . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9 Arduino Mega 2560 Host Processor–the ATmega2560 . . . . . . . . . . . . . . . 1.9.1 Arduino Mega 2560 /ATmega2560 Hardware Features . . . . . . . 1.9.2 ATmega2560 Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.3 ATmega2560 Port System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.4 ATmega2560 Internal Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.10 Arduino Mega 2560 Open Source Schematic . . . . . . . . . . . . . . . . . . . . . . . 1.11 LilyPad Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.11.1 LilyPad Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.12 Extending the Hardware Features of the Arduino Platforms . . . . . . . . . . .

3 4 4 6 6 7 8 8 8 15 16 17 17 18 20 20 24 24 26 26 27 29 31 34 34 34 34

ix

x

Contents

1.13 Application: SD Card with Real Time Clock and TFT Display . . . . . . . . 1.13.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.2 SD Card with RTC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.3 TFT Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.4 BioMedVue–Heart Arrhythmia Displays . . . . . . . . . . . . . . . . . . . . 1.13.5 SD Card and TFT Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.6 Arrhythmia Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.7 Sine and Cosine Signal Generator . . . . . . . . . . . . . . . . . . . . . . . . . 1.14 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.15 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

35 35 37 40 41 45 45 46 48 48 48

2 Arduino Subsystems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Analog–to–Digital Conversion (ADC) Subsystem . . . . . . . . . . . . . . . . . . . 2.2.1 Sampling, Quantization and Encoding . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Resolution and Data Rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.3 Analog–to–Digital Conversion (ADC) Process . . . . . . . . . . . . . . . 2.2.4 Transducer Interface Design (TID) Circuit . . . . . . . . . . . . . . . . . . 2.2.5 ADC Conversion Technologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.6 The Arduino UNO R3 and ATmega2560 ADC System . . . . . . . 2.2.7 Programming the ADC with the Arduino Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.8 One–Bit ADC–Threshold Detector . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.9 Digital–to–Analog Conversion (DAC) . . . . . . . . . . . . . . . . . . . . . . 2.2.10 DAC with the Arduino Development Environment . . . . . . . . . . . 2.2.11 DAC with External Converters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Timing Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 Timing Related Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Timing System Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.3 Programming the Arduino Using the Built–in Timing Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Serial Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 Serial Communication Terminology . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Serial USART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.3 USART Programming with the ADE–Serial LCD . . . . . . . . . . . . 2.5 Serial Peripheral Interface–SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1 SPI Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 SPI Programming in the Arduino Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.3 LED Strip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.4 SPI LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

51 52 52 53 56 57 58 58 58 59 65 65 67 68 68 68 70 70 71 71 73 74 76 76 77 78 83

Contents

2.6

xi

Two Wire Interface (TWI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6.1 Programming the TWI Subsystem with the Arduino IDE . . . . . 2.6.2 TWI LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7 Interrupt Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.1 General Interrupt Response . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.2 Programming External Interrupts Using the Arduino Development Environment Built–in Features . . . . . . . . . . . . . . . . 2.7.3 Foreground and Background Processing . . . . . . . . . . . . . . . . . . . . 2.8 Application: BME280 Humidity, Barometric Pressure, Temp Sensor . . . 2.8.1 BME 820 Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8.2 Monochrome OLED Display Using SPI or I2C . . . . . . . . . . . . . . 2.8.3 TWI/I2C with the Arduino LilyPad . . . . . . . . . . . . . . . . . . . . . . . . 2.8.4 Networking on the TWI/I2C Bus . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

85 86 87 89 90 90 91 94 94 98 102 103 103 104 105

3 Arduino Power and Interfacing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Powering an Arduino–Based Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Arduino Power Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2 Project Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.3 AC Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.4 DC Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.5 Remote DC Power–Solar Power System . . . . . . . . . . . . . . . . . . . . 3.3 Operating Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 HC CMOS Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.2 Level Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Input Devices–Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Switch Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.2 Pullup Resistors in Switch Interface Circuitry . . . . . . . . . . . . . . . 3.4.3 Switch Debouncing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.4 Keypads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Input Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.1 Digital Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.2 Analog Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6 Input Sensor Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1 Temperature Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.2 Light Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.3 Orientation Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.4 Environmental Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

107 107 108 108 109 109 110 113 114 115 118 122 124 124 124 125 130 130 131 136 137 139 145 155

xii

Contents

3.7

Output Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.1 Light Emitting Diodes (LEDs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.2 Seven Segment LED Displays–Small . . . . . . . . . . . . . . . . . . . . . . . 3.7.3 Seven Segment LED Displays–Large . . . . . . . . . . . . . . . . . . . . . . . 3.7.4 Serial LCD Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.5 TFT Displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.6 Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8 Application: Pulse Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.10 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Part II

159 160 161 161 166 166 166 171 172 172 173

Measuring Signals from the Human Body

4 Operational Amplifiers and Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Operational Amplifier Origins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Ideal Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Nonideal Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5 Configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Transducer Interface Design (TID) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Active Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.1 Signal Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.2 Filter Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.3 Filter Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.4 Active Analog RC Filter Design . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8 Instrumentation Amplifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.9 Isolation Amplifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.10 Application: Single–Lead Heart Rate Monitor-AD8232 . . . . . . . . . . . . . . 4.11 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.12 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

177 177 178 178 180 181 183 186 186 187 190 191 192 192 192 196 196 197

5 Biopotentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Origins of Biopotentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1 Biological Neuron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Electrodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.2 Some Practical Matters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.3 Electrocardiogram (ECG) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

199 199 200 203 203 206 208 208

Contents

xiii

5.3.4 Electroencephalogram (EEG) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.5 Electromyogram the EMG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4 Application: Biomedical Signals with TFT Display . . . . . . . . . . . . . . . . . . 5.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.6 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Part III

214 218 224 225 225 225

Design of Medical Instrumentation

6 Embedded Systems Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 What is an Embedded System? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Embedded System Design Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 Project Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.2 Background Research . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.3 Pre–design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.4 Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.5 Implement Prototype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.6 Preliminary Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.7 Complete and Accurate Documentation . . . . . . . . . . . . . . . . . . . . . 6.4 Application: Visual Feedback Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.2 Design Iteration I: Baseline Instrument . . . . . . . . . . . . . . . . . . . . . 6.4.3 Design Iteration II: Improved Features . . . . . . . . . . . . . . . . . . . . . 6.4.4 Design Iteration III: Arduino–Based Design . . . . . . . . . . . . . . . . . 6.4.5 Concluding Remarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.6 Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

229 229 230 230 230 232 232 232 234 235 235 236 236 237 242 247 256 258 259 259

Appendix A: Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

261

Appendix B: Programming in C with the Microchip ATmega328 . . . . . . . . . . . .

267

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

297

About the Author

Steven F. Barrett Ph.D., P.E., received the BS Electronic Engineering Technology from the University of Nebraska at Omaha in 1979, the M.E.E.E. from the University of Idaho at Moscow in 1986, and the Ph.D. from The University of Texas at Austin in 1993. He was formally an active duty faculty member at the United States Air Force Academy, Colorado and is now the Vice Provost of Undergraduate Education at the University of Wyoming and Professor of Electrical and Computer Engineering. He is a member of IEEE (Life Senior) and Tau Beta Pi (Chief Faculty Advisor). His research interests include digital and analog image processing, computer-assisted laser surgery, and embedded controller systems. He is a registered Professional Engineer in Wyoming and Colorado. He cowrote with Dr. Daniel Pack several textbooks on microcontrollers and embedded systems. In 2004, he was named “Wyoming Professor of the Year” by the Carnegie Foundation for the Advancement of Teaching and in 2008 was the recipient of the National Society of Professional Engineers (NSPE) Professional Engineers in Higher Education, Engineering Education Excellence Award. In 2023, he received the National Council of Examiners for Engineering and Surveying (NCEES) Distinguished Examination Service Award.

xv

Part I Introduction to Arduino, the IDE, Programming, and Interfacing

1

Getting Started

Objectives: After reading this chapter, the reader should be able to do the following: • Successfully download and execute a simple program using the Arduino Development Environment; • Describe the key features of the Arduino Development Environment; • List the programming support information available at the Arduino home page; • Write programs for use on the Arduino UNO R3, Mega 2560 R3, and the LilyPad Arduino processing boards; • Describe the Arduino concept of open source hardware; • Diagram the layout of the Arduino UNO R3 processor board; • Name and describe the different features aboard the Arduino UNO R3 processor board; • Discuss the features and functions of the Microchip ATmega328; • Diagram the layout of the Arduino Mega 2560 processor board; • Name and describe the different features aboard the Arduino Mega 2560 R3 processor board; • Discuss the features and functions of the Microchip ATmega2560; • Diagram the layout of the Arduino LilyPad; • Name and describe the different features aboard the Arduino LilyPad; • Discuss the features and functions of the LilyPad; and • Describe how to extend the hardware features of the Arduino processor using Arduino shields.

© The Author(s), under exclusive license to Springer Nature Switzerland AG 2024 S. F. Barrett, Arduino VI, Synthesis Lectures on Digital Circuits & Systems, https://doi.org/10.1007/978-3-031-47130-8_1

3

4

1.1

1 Getting Started

Overview

Welcome to the world of Arduino! The Arduino concept of open source hardware was developed by the visionary Arduino team of Massimo Banzi, David Cuartilles, Tom Igoe, Gianluca Martino, and David Mellis in Ivrea, Italy. The team’s goal was to develop a line of easy–to–use microcontroller hardware and software such that processing power would be readily available to everyone. This chapter provides a tutorial on the Arduino programming environment and some of the Arduino hardware platforms. To the novice, programming a microcontroller may appear mysterious, complicated, overwhelming, and difficult. When faced with a new task, one often does not know where to start. The goal of this chapter is to provide a tutorial on how to begin programming with Arduino. We will use a top–down design approach. We begin with the “big picture” of the chapter. We then discuss the Ardunio Development Environment and how it may be used to quickly develop a program (sketch) for the Arduino UNO R3, the Arduino Mega 2560 R3, and the LilyPad Arduino processor boards. Throughout the chapter, we provide examples and also provide pointers to a number of excellent references. To get the most out of this chapter, it is highly recommended to work through each example. In the second portion of the chapter we explore the different Arduino processing boards used throughout the book.1

1.2

The Big Picture

We begin with the big picture of how to program different Arduino development boards as shown in Fig. 1.1. This will help provide an overview of how chapter concepts fit together. Most microcontrollers are programmed with some variant of the C programming language. The C programming language provides a nice balance between the programmer’s control of the microcontroller hardware and time efficiency in program writing. As an alternative, the Arduino Development Environment (ADE) provides a user–friendly interface to quickly develop a program, transform the program to machine code, and then load the machine code into the Arduino processor in several simple steps. We use the ADE throughout the book. You will find the syntax used in the Arduino ADE similar to C programming. A tutorial on C programming is provided in Appendix B. The first version of the Arduino Development Environment was released in August 2005. It was developed at the Interaction Design Institute in Ivrea, Italy to allow students the ability to quickly put processing power to use in a wide variety of projects. Since that time, updated versions incorporating new features, have been released on a regular basis (www.arduino.cc). 1 This chapter was adapted with permission from “Arduino I Getting Started, S.F. Barrett, Morgan &

Claypool Publishers, 2020, Chaps. 1, 2.

1.2 The Big Picture

5

Arduino Development Environment

computer USB Arduino Development Environment

Arduino UNO R3 USB

Arduino MEGA 2560 R3 USB2

Arduino USB2SERIAL LilyPad Arduino

Fig. 1.1 Programming the Arduino processor board. (Arduino illustrations used with permission of the Arduino Team (CC BY–NC–SA) www.arduino.cc)

6

1 Getting Started

At its most fundamental level, the Arduino Development Environment is a user–friendly interface to allow one to quickly write, load, and execute code on a microcontroller. A barebones program need only consist of a setup() and loop() function. The Arduino Development Environment adds the other required pieces such as header files and the main program construct. The ADE is written in Java and has its origins in the Processor programming language and the Wiring Project (www.arduino.cc).

1.3

Arduino Quickstart

To get started using an Arduino–based platform, you will need the following hardware and software. • • • •

an Arduino–based hardware processing platform, the appropriate interface cable from the host PC or laptop to the Arduino platform, an Arduino compatible power supply, and the Arduino software.

Interface cable. The UNO and the MEGA connect to a host PC via a USB cable (type A male to type B female). The LilyPad requires a USB 2 serial converter (Arduino USB2SERIAL) and an USB 2 cable (Type A male to mini type B female). Power supply. The Arduino processing boards may be powered from the USB port during project development. However, it is highly recommended that an external power supply be employed. This will allow developing projects beyond the limited electrical current capability of the USB port. For the UNO and the MEGA platforms, Arduino www.arduino.cc recommends a power supply from 7–12 VDC with a 2.1 mm center positive plug. A power supply of this type is readily available from a number of electronic parts supply companies. For example, the Jameco #133891 power supply is a 9 VDC model rated at 300 mA and equipped with a 2.1 mm center positive plug. It is available for under US$10. Both the UNO and MEGA have onboard voltage regulators that maintain the incoming power supply voltage to a stable 5 VDC.

1.3.1

Quick Start Guide

The Arduino Development Environment may be downloaded from the Arduino website’s front page at www.arduino.cc. Versions are available for Windows, Mac OS X, and Linux. Provided below is a quick start step–by–step approach to blink an onboard LED. • Download the Arduino Development Environment from www.arduino.cc.

1.3

Arduino Quickstart

7

• Connect the Arduino UNO R3 processing board to the host computer via a USB cable (A male to B male). • Start the Arduino Development Environment. • Under the Tools tab select the evaluation Board you are using and the Port that it is connected to. • Type the following program. //***************************************************************** #define LED_PIN 13 void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500); }

//delay specified in ms

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

• Upload and execute the program by asserting the “Upload” (right arrow) button. • The onboard LED should blink at one second intervals. With the Arduino ADE downloaded and exercised, let’s take a closer look at its features.

1.3.2

Arduino Development Environment Overview

The Arduino Development Environment is illustrated in Fig. 1.2. The ADE contains a text editor, a message area for displaying status, a text console, a tool bar of common functions, and an extensive menuing system. The ADE also provides a user–friendly interface to the Arduino processor board which allows for a quick upload of code. This is possible because the Arduino processing boards are equipped with a bootloader program.

8

1 Getting Started Upload Verify List of sketches

Board Manager Library Manager Debug Search

Fig. 1.2 Arduino Development Environment (www.arduino.cc)

1.3.3

Sketchbook Concept

In keeping with a hardware and software platform for students of the arts, the Arduino environment employs the concept of a sketchbook. An artist maintains their works in progress in a sketchbook. Similarly, we maintain our programs within a sketchbook in the Arduino environment. Furthermore, we refer to individual programs as sketches. An individual sketch within the sketchbook may be accessed via the Sketchbook entry under the file tab.

1.3.4

Arduino Software, Libraries, and Language References

The Arduino Development Environment has a number of built–in features. Some of the features may be directly accessed via the Arduino Development Environment drop down toolbar illustrated in Fig. 1.2. Provided in Fig. 1.3 is a handy reference to show the available features. The toolbar provides a wide variety of features to compose, compile, load and execute a sketch.

1.3.5

Writing an Arduino Sketch

The basic format of the Arduino sketch consists of a “setup” and a “loop” function. The setup function is executed once at the beginning of the program. It is used to configure pins, declare variables and constants, etc. The loop function will execute sequentially step–by-

1.3

Arduino Quickstart

9 Menu

File - New - Open - Sketchbook - Examples - Close - Save - Save As - Preferences - Advanced - Quit

Edit - Undo - Redo - Cut - Copy - Copy for Forum - Paste - Select All - Go to line... - Comment/ Uncomment - Increase Indent - Decrease Indent - Auto Format - Replace in Files - Increase Font Size - Decrease Font Size - Find - Find Next - Find Previous - Use Selection for Find

Sketch - Verify/Compile - Upload - Configure and Upload - Upload Using Programmer - Export Compiled Binary - Optimize for Debugging - Show Sketch Folder - Include Library - Add File

Tools - Auto Format - Archive Sketch - Manage Libraries - Serial Monitor - Serial Plotter - Board: xxx - Get Board Info - WiFi101/WiFi NINA Firmware Updater - Upload SSL Root Certificates - Burn Bootloader

Help - Getting Started - Environment - Troubleshooting - Reference - Find in Reference - Frequently Asked Questions - Visit Arduino.cc - Privacy Policy - Check for Arduino IDE Updates - About Arduino IDE

Fig. 1.3 Arduino Development Environment menu (www.arduino.cc)

–step. When the end of the loop function is reached it will automatically return to the first step of the loop function and execute again. This goes on continuously until the program is stopped. //********************************************************** void setup() { //place setup code here } void loop() { //main code steps are provided here : : } //**********************************************************

Example: Let’s revisit the sketch provided earlier in the chapter. //********************************************************** #define LED_PIN 13

//name pin 13 LED_PIN

10

void setup() { pinMode(LED_PIN, OUTPUT); } void loop() { digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(500); }

1 Getting Started

//set pin to output

//write //delay //write //delay

pin to logic high specified in ms to logic low specified in ms

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

In the first line the #define statement links the designator “LED_PIN” to pin 13 on the Arduino processor board. In the setup function, LED_PIN is designated as an output pin. Recall the setup function is only executed once. The program then enters the loop function that is executed sequentially step–by–step and continuously repeated. In this example, the LED_PIN is first set to logic high to illuminate the LED onboard the Arduino processing board. A 500 ms delay then occurs. The LED_PIN is then set low. A 500 ms delay then occurs. The sequence then repeats. Even the most complicated sketches follow the basic format of the setup function followed by the loop function. To aid in the development of more complicated sketches, the Arduino Development Environment has many built–in features that may be divided into the areas of structure, variables and functions. The structure and variable features follow rules similar to the C programming language which is discussed in Appendix B. The built–in functions consists of a set of pre–defined activities useful to the programmer. These built–in functions are summarized in Fig. 1.4. There are many program examples available to allow the user to quickly construct a sketch. These programs are summarized in Fig. 1.5. Complete documentation for these programs is available at the Arduino homepage [www.arduino.cc]. This documentation is easily accessible via the Help tab on the Arduino Development Environment toolbar. This documentation will not be repeated here. Instead, we refer to these features at appropriate places throughout the remainder of the book. With the Arduino open source concept, users throughout the world are constantly adding new built–in features. As new features are added, they will be released in future Arduino Development Environment versions. As an Arduino user, you too may add to this collection of useful tools. We continue with another example. Example: In this example we connect an external LED to Arduino UNO R3 pin 12. The onboard LED will blink alternately with the external LED. The external LED is connected to the Arduino UNO R3 as shown in Fig. 1.6. The LED has a positive (anode) and negative

1.3

Arduino Quickstart

11 Arduino Functions

Advanced I/O tone( ) notone( ) shiftOut( ) shiftIn( ) pulseIn( )

Digital I/O pinMode( ) digitalWrite( ) digitalRead( )

Fig. 1.4 Arduino Development Environment functions (www.arduino.cc) Arduino Environment Built-in Programs

Digital Input/Output - Blink (under Basics) - Blink without delay - Button - Debounce - Digital Input Pullup - State Change Detection - tone Keyboard - tone Melody - tone Multiple - tone Pitch Follower

Analog Input/Output - Analog InOut Serial - Analog Input - Analog Write Mega - Calibration - Fading - Smoothing

Control Structures - Array - For loop interation - If statement conditional - Switch case - Switch case 2 - While statement conditional

Sensors - ADX3xx accelerometer - Knock detector - Memsic2125 two-axis accelerometer - Ping ultrasonic range finder

Communication - ASCII Table - Dimmer - Graph - MIDI - MultiSerial - Physical pixel - Read ASCII String - Serial call response - Serial call response ASCII - Serial Event - Serial Passthrough - Virtual color mixer

Multiple Libraries - Strings - USB - LCD - Robot Control - Robot Motor - SD card - Servo - Stepper :

Fig. 1.5 Arduino Development Environment built–in features (www.arduino.cc)

12

1 Getting Started

220

+ -

(a) schematic

220

(b) circuit layout

Fig. 1.6 Arduino UNO R3 with an external LED. (UNO R3 illustration used with permission of the Arduino Team (CC BY–NC–SA) www.arduino.cc)

(cathode) lead. As you look down from above, a round LED has a flat side. The lead closest to the flat side is the cathode. In the bottom right portion of the figure, a cutaway is provided of a prototype board. Prototype boards provide a convenient method of interconnecting electronic components. The boards are configured to accept dual inline package (DIP) integrated circuits (ICs or chips). The ICs are placed to straddle the center channel. Other components may also be

1.3

Arduino Quickstart

13

placed on the boards. The boards are covered with multiple connection points. Typically, the board’s connection points are arranged in columns and five connection point rows. The connection points in a column are connected at the board’s base by a conductor. Also, connection points in a board row are connected. The connection points readily accept insulated, solid 22 AWG insulated wire. This wire type is available in variety of colors (www.jameco.com). To connect two circuit points together, estimate the length of wire needed to connect the points. Cut the solid 22 AWG insulated wire to that length plus an additional one–half inch (approximately 13 mm). Using a wire stripper (e.g. Jameco #159291), strip off approximately one–quarter inch (7.5 mm) from each end of the wire. The conductor exposed ends of the wire can then be placed into appropriate circuit locations for a connection. Once a wire end is placed in a breadboard hole, the exposed conductor should not be visible. Circuit connections may also be made using prefabricated jumper wires. These are available from a number of sources such as Jameco (www.jameco.com), Adafruit (www.adafruit.com), and SparkFun Electronics (www.sparkfun.com). //********************************************************** #define int_LED 13 #define ext_LED 12

//name pin 13 int_LED //name pin 12 ext_LED

void setup() { pinMode(int_LED, OUTPUT); pinMode(ext_LED, OUTPUT); } void loop() { digitalWrite(int_LED, digitalWrite(ext_LED, delay(500); digitalWrite(int_LED, digitalWrite(ext_LED, delay(500); }

HIGH); LOW); LOW); HIGH);

//set pin to output //set pin to output

//set pin logic high //set pin logic low //delay specified in ms //set pin logic low //set pin logic high

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

Example: In this example we connect an external LED to Arduino UNO R3 pin 12 and an external switch attached to pin 11. The onboard LED will blink alternately with the external LED when the switch is depressed. The external LED and switch is connected to the Arduino UNO R3 as shown in Fig. 1.7.

14

1 Getting Started

220 5 VDC 4.7K

(a) schematic

220

(b) circuit layout

4.7K

Fig. 1.7 Arduino UNO R3 with an external LED. (UNO R3 illustration used with permission of the Arduino Team (CC BY–NC–SA) www.arduino.cc)

1.4

Arduino Platforms

15

//********************************************************** #define int_LED 13 #define ext_LED 12 #define ext_sw 11

//name pin 13 int_LED //name pin 12 ext_LED //name pin 11 ext_sw

int switch_value;

//integer variable to //store switch status

void setup() { pinMode(int_LED, OUTPUT); pinMode(ext_LED, OUTPUT); pinMode(ext_sw, INPUT); } void loop() { switch_value = digitalRead(ext_sw); if(switch_value == LOW) { digitalWrite(int_LED, HIGH); digitalWrite(ext_LED, LOW); delay(50); digitalWrite(int_LED, LOW); digitalWrite(ext_LED, HIGH); delay(50); } else { digitalWrite(int_LED, LOW); digitalWrite(ext_LED, LOW); } }

//set pin to output //set pin to output //set pin to input

//read switch status //if switch at logic low, //do steps with braces //set pin logic high //set pin logic low //delay 50 ms //set pin logic low //set pin logic high //delay 50ms //if switch at logic high, //do steps between braces //set pins low //set pins low

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

1.4

Arduino Platforms

Throughout the book, we use three different Arduino processing boards: the Arduino UNO R3 board (UNO), the Arduino Mega 2560 REV3 board (MEGA), and the Arduino LilyPad. Starter kits for these platforms are available from a number of sources.

16

1 Getting Started

1.5

Arduino UNO R3 Processing Board

digital I/O m

re

om

fe

lc ria se

PW

M

re og al an

LED USB-to-serial converter TX LED RX LED

nc

e

The Arduino UNO R3 processing board is illustrated in Fig. 1.8. Working clockwise from the left, the board is equipped with a USB connector to allow programming the processor from a host personal computer (PC) or laptop. The board may also be programmed using In System Programming (ISP) techniques. A 6–pin ISP programming connector is on the opposite side of the board from the USB connector. The board is equipped with a USB–to–serial converter to allow compatibility between the host PC and the serial communications systems aboard the Microchip ATmega328 processor. The UNO R3 is also equipped with several small surface mount light emitting diodes (LEDs) to indicate serial transmission (TX) and reception (RX) and an extra LED for project use. The header strip at the top of the board provides access for an analog reference signal, pulse width modulation (PWM) signals, digital input/output (I/O), and serial communications. The header strip at the bottom of the board provides analog inputs for the analog–to–digital (ADC) system and power supply terminals. Finally, the external power supply connector is provided at the bottom left corner of the board. The top and bottom header strips conveniently mate with an Arduino shield to extend the features of the Arduino host processor.

switch

LED power indicator

USB connector (to PC) ISP programming connector

timebase

power supply connector (7-12 VDC) power supply terminals

analog inputs

Fig. 1.8 Arduino UNO R3 layout. (Figure adapted and used with permission of Arduino Team (CC BY–NC–SA) (www.arduino.cc).)

1.6

Arduino UNO R3 Host Processor–the ATmega328

1.6

17

Arduino UNO R3 Host Processor–the ATmega328

The host processor for the Arduino UNO R3 is the Microchip Atmega328. The “328” is a 28 pin, 8–bit microcontroller. The architecture is based on the Reduced Instruction Set Computer (RISC) concept which allows the processor to complete 20 million instructions per second (MIPS) when operating at 20 MHz. The “328” is equipped with a wide variety of features as shown in Fig. 1.9. The features may be conveniently categorized into the following systems: • Memory system, • Port system, • Timer system, • Analog–to–digital converter (ADC), • Interrupt system, and • Serial communications.

1.6.1

Arduino UNO R3/ATmega328 Hardware Features

The Arduino UNO R3’s processing power is provided by the ATmega328. The pin out diagram and block diagram for this processor are provided in Figs. 1.10 and 1.11. In this section, we provide a brief overview of the systems aboard the processor.

Arduino UNO R3 hoste d on the ATme ga 328

Memory System - 32K byte, ISP programmable flash - 1K byte, byte addressable EEPROM - 2K byte RAM

Timer System - Two 8-bit timer/counter - One 16-bit timer/counter - Six PWM channels

Port System - 14 digital I/O pins -- 6 provide PWM - 6 analog input pins

Fig. 1.9 Arduino UNO R3 systems

Analog-to-digital converter - 6 channel 10-bit ADC (PDIP)

Serial Communications - Serial USART - Serial peripheral interface - Two wire interface (TWI)

Interrupt System - 26 total interrupts - 2 external pin interrupts

18

1 Getting Started

Fig. 1.10 ATmega328 pin out (Figure used with permission of Microchip, Incorporated)

1.6.2

ATmega328 Memory

The ATmega328 is equipped with three main memory sections: flash electrically erasable programmable read only memory (EEPROM), static random access memory (SRAM), and byte–addressable EEPROM. We discuss each memory component in turn.

1.6.2.1 ATmega328 In–System Programmable Flash EEPROM Bulk programmable flash EEPROM is used to store programs. It can be erased and programmed as a single unit. Also, should a program require a large table of constants, it may be included as a global variable within a program and programmed into flash EEPROM with the rest of the program. Flash EEPROM is nonvolatile meaning memory contents are retained even when microcontroller power is lost. The ATmega328 is equipped with 32K bytes of onboard reprogrammable flash memory. This memory component is organized into 16K locations with 16 bits at each location.

1.6.2.2 ATmega328 Byte–Addressable EEPROM Byte–addressable EEPROM memory is used to permanently store and recall variables during program execution. It too is nonvolatile. It is especially useful for logging system malfunctions and fault data during program execution. It is also useful for storing data that must be retained during a power failure but might need to be changed periodically. Examples where this type of memory is used are found in applications to store system parameters, electronic lock combinations, and automatic garage door electronic unlock sequences. The ATmega328 is equipped with 1024 bytes of EEPROM.

1.6

Arduino UNO R3 Host Processor–the ATmega328

Fig. 1.11 ATmega328 block diagram (Figure used with permission of Microchip, Incorporated)

19

20

1 Getting Started

1.6.2.3 ATmega328 Static Random Access Memory (SRAM) Static RAM memory is volatile. That is, if the microcontroller loses power, the contents of SRAM memory are lost. It can be written to and read from during program execution. The ATmega328 is equipped with 2K bytes of SRAM. A small portion of the SRAM is set aside for the general–purpose registers used by the processor and also for the input/output and peripheral subsystems aboard the microcontroller. A header file provides the link between register names used in a program and their physical description and location in memory. During program execution, RAM is used to store global variables, support dynamic memory allocation of variables, and to provide a location for the stack.

1.6.3

ATmega328 Port System

The Microchip ATmega328 is equipped with four, 8–bit general purpose, digital input/output (I/O) ports designated PORTB (8 bits, PORTB[7:0]), PORTC (7 bits, PORTC[6:0]), and PORTD (8 bits, PORTD[7:0]). As shown in Fig. 1.12, each port has three registers associated with it: • Data Register PORTx –used to write output data to the port, • Data Direction Register DDRx – used to set a specific port pin to either output (1) or input (0), and • Input Pin Address PINx – used to read input data from the port. Figure 1.12b describes the settings required to configure a specific port pin to either input or output. If selected for input, the pin may be selected for either an input pin or to operate in the high impedance (Hi–Z) mode. If selected for output, the pin may be further configured for either logic low or logic high. Port pins are usually configured at the beginning of a program for either input or output and their initial values are then set. Usually all eight pins for a given port are configured simultaneously.

1.6.4

ATmega328 Internal Systems

In this section, we provide a brief overview of the internal features of the ATmega328. It should be emphasized that these features are the internal systems contained within the confines of the microcontroller chip. These built–in features allow complex and sophisticated tasks to be accomplished by the microcontroller.

1.6

Arduino UNO R3 Host Processor–the ATmega328

21

Port x Data Register - PORTx 7

0

Port x Data Direction Register - DDRx 7

0

Port x Input Pins Address - PINx 7

0 (a) port associated registers

DDxn

PORTxn

I/O

Comment

Pullup

0

0

input

Tri-state (Hi-Z)

No

0

1

input

source current if externally pulled low

Yes

1

0

output

Output Low (Sink)

No

1

1

output

Output High (Source)

No

x: port designator (B, C, D) n: pin designator (0 - 7) (b) port pin configuration

Fig. 1.12 ATmega328 port configuration registers

1.6.4.1 ATmega328 Time Base The microcontroller is a complex synchronous state machine. It responds to program steps in a sequential manner as dictated by a user–written program. The microcontroller sequences through a predictable fetch–decode–execute sequence. Each unique assembly language program instruction issues a series of signals to control the microcontroller hardware to accomplish instruction related operations. The speed at which a microcontroller sequences through these actions is controlled by a precise time base called the clock. The clock source is routed throughout the microcontroller to provide a time base for all peripheral subsystems. The ATmega328 may be clocked internally using a user–selectable resistor capacitor (RC) time base or it may be clocked

22

1 Getting Started

externally. The RC internal time base is selected using programmable fuse bits. You may choose from several different internal fixed clock operating frequencies. To provide for a wider range of frequency selections an external time source may be used. The external time sources, in order of increasing accuracy and stability, are an external RC network, a ceramic resonator, or a crystal oscillator. The system designer chooses the time base frequency and clock source device appropriate for the application at hand. Generally speaking, if the microcontroller will be interfaced to external peripheral devices either a ceramic resonator or a crystal oscillator should be used as a time base.

1.6.4.2 ATmega328 Timing Subsystem The ATmega328 is equipped with a complement of timers which allows the user to generate a precision output signal, measure the characteristics (period, duty cycle, frequency) of an incoming digital signal, or count external events. Specifically, the ATmega328 is equipped with two 8–bit timer/counters and one 16–bit counter.

1.6.4.3 Pulse Width Modulation Channels A pulse width modulated or PWM signal is characterized by a fixed frequency and a varying duty cycle. Duty cycle is the percentage of time a repetitive signal is logic high during the signal period. It may be formally expressed as: dut y cycle[%] = (on time/ period) × (100%)

.

The ATmega328 is equipped with four pulse width modulation (PWM) channels. The PWM channels coupled with the flexibility of dividing the time base down to different PWM subsystem clock source frequencies allows the user to generate a wide variety of PWM signals: from relatively high frequency low duty cycle signals to relatively low frequency high duty cycle signals. PWM signals are used in a wide variety of applications including controlling the position of a servo motor and controlling the speed of a DC motor.

1.6.4.4 ATmega328 Serial Communications The ATmega328 is equipped with a variety of different serial communication subsystems including the Universal Synchronous and Asynchronous Serial Receiver and Transmitter (USART), the serial peripheral interface (SPI), and the Two–wire Serial Interface. What these systems have in common is the serial transmission of data. In a serial communications transmission, serial data is sent a single bit at a time from transmitter to receiver. ATmega328 Serial USART The serial USART may be used for full duplex (two way) communication between a receiver and transmitter. This is accomplished by equipping the

1.6

Arduino UNO R3 Host Processor–the ATmega328

23

ATmega328 with independent hardware for the transmitter and receiver. The USART is typically used for asynchronous communication. That is, there is not a common clock between the transmitter and receiver to keep them synchronized with one another. To maintain synchronization between the transmitter and receiver, framing start and stop bits are used at the beginning and end of each data byte in a transmission sequence. The ATmega328 USART is quite flexible. It has the capability to be set to different data transmission rates known as the Baud (bits per second) rate. The USART may also be set for data bit widths of 5 to 9 bits with one or two stop bits. Furthermore, the ATmega328 is equipped with a hardware generated parity bit (even or odd) and parity check hardware at the receiver. A single parity bit allows for the detection of a single bit error within a byte of data. The USART may also be configured to operate in a synchronous mode. ATmega328 Serial Peripheral Interface–SPI The ATmega328 Serial Peripheral Interface (SPI) can also be used for two–way serial communication between a transmitter and a receiver. In the SPI system, the transmitter and receiver share a common clock source. This requires an additional clock line between the transmitter and receiver but allows for higher data transmission rates as compared to the USART. The SPI may be viewed as a synchronous 16–bit shift register with an 8–bit half residing in the transmitter and the other 8–bit half residing in the receiver. The transmitter is designated the master since it is providing the synchronizing clock source between the transmitter and the receiver. The receiver is designated as the slave. ATmega328 Two–wire Serial Interface–TWI The TWI subsystem allows the system designer to network related devices (microcontrollers, transducers, displays, memory storage, etc.) together into a system using a two–wire interconnecting scheme. The TWI allows a maximum of 128 devices to be interconnected. Each device has its own unique address and may both transmit and receive over the two–wire bus at frequencies up to 400 kHz. This allows the device to freely exchange information with other devices in the network within a small area.

1.6.4.5 ATmega328 Analog to Digital Converter–ADC The ATmega328 is equipped with an eight–channel analog to digital converter (ADC) subsystem. The ADC converts an analog signal from the outside world into a binary representation suitable for use by the microcontroller. The ATmega328 ADC has 10–bit resolution. This means that an analog voltage between 0 and 5 V will be encoded into one of 1024 binary representations between .(000)16 and .(3F F)16 . This provides the ATmega328 with a voltage resolution of approximately 4.88 mV.

1.6.4.6 ATmega328 Interrupts The normal execution of a program follows a designated sequence of instructions. However, sometimes this normal sequence of events must be interrupted to respond to high priority

24

1 Getting Started

faults and status both inside and outside the microcontroller. When these higher priority events occur, the microcontroller suspends normal operation and executes event specific actions contained within an interrupt service routine (ISR). Once the higher priority event has been serviced by the ISR, the microcontroller returns and continues processing the normal program. The ATmega328 is equipped with a complement of 26 interrupt sources. Two of the interrupts are provided for external interrupt sources while the remaining interrupts support the efficient operation of peripheral subsystems aboard the microcontroller.

1.7

Arduino UNO R3 Open Source Schematic

The entire line of Arduino products is based on the visionary concept of open source hardware and software. That is, hardware and software developments are openly shared among users to stimulate new ideas and advance the Arduino concept. In keeping with the Arduino concept, the Arduino team openly shares the schematic of the Arduino UNO R3 processing board. Reference Fig. 1.13.

1.8

Arduino Mega 2560 R3 Processing Board

The Arduino Mega 2560 REV3 (R3) processing board is illustrated in Fig. 1.14. Working clockwise from the left, the board is equipped with a USB connector to allow programming the processor from a host PC. The board may also be programmed using In System Programming (ISP) techniques. A 6–pin ISP programming connector is on the opposite side of the board from the USB connector. The board is equipped with a USB–to–serial converter to allow compatibility between the host PC and the serial communications systems aboard the ATmega2560 processor. The Mega 2560 R3 is also equipped with several small surface mount LEDs to indicate serial transmission (TX) and reception (RX) and an extra LED for project use. The header strip at the top of the board provides access to pulse width modulation (PWM) signals and serial communications. The header strip at the right side of the board provides access to multiple digital input/output pins. The bottom of the board provides analog inputs for the analog–to–digital (ADC) system and power supply terminals. Finally, the external power supply connector is provided at the bottom left corner of the board. The header strips conveniently mate with an Arduino shield (to be discussed shortly) to extend the features of the host processor.

Arduino Mega 2560 R3 Processing Board

Fig. 1.13 Arduino UNO R3 open source schematic. (Figure adapted and used with permission of the Arduino Team (CC BY–NC–SA) (www.arduino. cc))

1.8 25

26

1 Getting Started USB-to-serial converter

pulse width modulation (PWM)

serial communications

ISP programming connector

USB connector (to PC) digital input/output timebase

power supply connector (7-12 VDC) power supply terminals

analog inputs

Fig. 1.14 Arduino Mega2560 layout (Figure adapted and used with permission of Arduino Team (CC BY–NC–SA) (www.arduino.cc))

1.9

Arduino Mega 2560 Host Processor–the ATmega2560

The host processor for the Arduino Mega 2560 is the Microchip Atmega2560. The “2560” is a 100 pin, surface mount 8–bit microcontroller. The architecture is based on the Reduced Instruction Set Computer (RISC) concept which allows the processor to complete 16 million instructions per second (MIPS) when operating at 16 MHz. The “2560” is equipped with a wide variety of features as shown in Fig. 1.15. The features may be conveniently categorized into the following systems: • • • • • •

Memory system, Port system, Timer system, Analog–to–digital converter (ADC), Interrupt system, and serial communications.

1.9.1

Arduino Mega 2560 /ATmega2560 Hardware Features

The Arduino Mega 2560s processing power is provided by the ATmega2560. The pin out diagram and block diagram for this processor are provided in Figs. 1.16 and 1.17. In this section, we provide a brief overview of the systems onboard the processor.

1.9

Arduino Mega 2560 Host Processor–the ATmega2560

27

Arduino Mega 2560 hosted on the ATmega2560

Memory System - 256K byte, ISP programmable flash - 4K byte, byte addressable EEPROM - 8K byte RAM

Analog-to-digital converter Timer System - Two 8-bit timer/counter - 16 channel 10-bit ADC - Four 16-bit timer/counter - Twelve PWM channels

Port System - 11 each 8-bit digital I/O ports on ATmega2560 - On Arduino Mega 2560 -- 54 digital I/O pins -- 14 can be used as PWM

Serial Communications - 4 channel Serial USART - Serial peripheral interface - Two wire interface (TWI)

Interrupt System - 57 total interrupts - 8 external pin interrupts - 3 pin change interrupts

Fig. 1.15 Arduino Mega 2560 systems

1.9.2

ATmega2560 Memory

The ATmega2560 is equipped with three main memory sections: flash electrically erasable programmable read only memory (EEPROM), static random access memory (SRAM), and byte–addressable EEPROM for data storage.

1.9.2.1 ATmega2560 In–System Programmable Flash EEPROM Bulk programmable flash EEPROM is used to store programs. It can be erased and programmed as a single unit. Also, should a program require a large table of constants, it may be included as a global variable within a program and programmed into flash EEPROM with the rest of the program. Flash EEPROM is nonvolatile meaning memory contents are retained when microcontroller power is lost. The ATmega2560 is equipped with 256K bytes of onboard reprogrammable flash memory.

1.9.2.2 ATmega2560 Byte–Addressable EEPROM Byte–addressable EEPROM memory is used to permanently store and recall variables during program execution. It too is nonvolatile. It is especially useful for logging system malfunctions and fault data during program execution. It is also useful for storing data that must be retained during a power failure but might need to be changed periodically. Examples where this type of memory is used are found in applications to store system parameters, electronic lock combinations, and automatic garage door electronic unlock sequences. The ATmega2560 is equipped with 4096 bytes of byte–addressable EEPROM.

28

1 Getting Started

Fig. 1.16 ATmega2560 pin out (Figure used with permission of Microchip, Incorporated)

1.9.2.3 ATmega2560 Static Random Access Memory (SRAM) Static RAM memory is volatile. That is, if the microcontroller loses power, the contents of SRAM memory are lost. It can be written to and read from during program execution. The ATmega2560 is equipped with 8K bytes of SRAM. A small portion of the SRAM is set aside for the general–purpose registers used by the processor and also for the input/output and peripheral subsystems aboard the microcontroller. During program execution, RAM is used to store global variables, support dynamic memory allocation of variables, and to provide a location for the stack.

1.9

Arduino Mega 2560 Host Processor–the ATmega2560

29

Fig. 1.17 ATmega2560 block diagram (Figure used with permission of Microchip, Incorporated)

1.9.3

ATmega2560 Port System

The Microchip ATmega2560 is equipped with eleven, 8–bit general purpose, digital input/output (I/O) ports designated: • • • • • • • • •

PORTA (8 bits, PORTA[7:0]) PORTB (8 bits, PORTB[7:0]) PORTC (7 bits, PORTC[7:0]) PORTD (8 bits, PORTD[7:0]) PORTE (8 bits, PORTE[7:0]) PORTF (8 bits, PORTF[7:0]) PORTG (7 bits, PORTG[7:0]) PORTH (8 bits, PORTH[7:0]) PORTJ (8 bits, PORTJ[7:0])

30

1 Getting Started

• PORTK (8 bits, PORTK[7:0]) • PORTL (7 bits, PORTL[7:0]) All of the ports also have alternate functions which will be described later. In this section, we concentrate on the basic digital I/O port features. As shown in Fig. 1.18, each port has three registers associated with it: • Data Register PORTx –used to write output data to the port, • Data Direction Register DDRx –used to set a specific port pin to either output (1) or input (0), and • Input Pin Address PINx –used to read input data from the port.

Port x Data Register - PORTx 7

0

Port x Data Direction Register - DDRx 7

0

Port x Input Pins Address - PINx 7

0 (a) port associated registers

DDxn

PORTxn

I/O

Comment

Pullup

0

0

input

Tri-state (Hi-Z)

No

0

1

input

source current if externally pulled low

Yes

1

0

output

Output Low (Sink)

No

1

1

output

Output High (Source)

No

x: port designator (B, C, D) n: pin designator (0 - 7) (b) port pin configuration

Fig. 1.18 ATmega2560 port configuration registers

1.9

Arduino Mega 2560 Host Processor–the ATmega2560

31

Figure 1.18b describes the settings required to configure a specific port pin to either input or output. If selected for input, the pin may be selected for either an input pin or to operate in the high impedance (Hi–Z) mode. If selected for output, the pin may be further configured for either logic low or logic high. Port pins are usually configured at the beginning of a program for either input or output and their initial values are then set. Usually all eight pins for a given port are configured simultaneously.

1.9.4

ATmega2560 Internal Systems

In this section, we provide a brief overview of the internal features of the ATmega2560. It should be emphasized that these features are the internal systems contained within the confines of the microcontroller chip. These built–in features allow complex and sophisticated tasks to be accomplished by the microcontroller.

1.9.4.1 ATmega2560 Time Base The microcontroller is a complex synchronous state machine. It responds to program steps in a sequential manner as dictated by a user–written program. The microcontroller sequences through a predictable fetch–decode–execute sequence. Each unique assembly language program instruction issues a series of signals to control the microcontroller hardware to accomplish instruction related operations. The speed at which a microcontroller sequences through these actions is controlled by a precise time base called the clock. The clock source is routed throughout the microcontroller to provide a time base for all peripheral subsystems. The ATmega2560 may be clocked internally using a user–selectable resistor capacitor (RC) time base or it may be clocked externally. The RC internal time base is selected using programmable fuse bits. You may choose an internal fixed clock operating frequency of 128 kHz or 8 MHz. The clock frequency may be prescaled by a number of different clock division factors (1, 2, 4, etc.). To provide for a wider range of frequency selections an external time source may be used. The external time sources, in order of increasing accuracy and stability, are an external RC network, a ceramic resonator, or a crystal oscillator. The system designer chooses the time base frequency and clock source device appropriate for the application at hand. Generally speaking, if the microcontroller will be interfaced to external peripheral devices either a ceramic resonator or a crystal oscillator should be used as a time base.

1.9.4.2 ATmega2560 Timing Subsystem The ATmega2560 is equipped with a complement of timers which allows the user to generate a precision output signal, measure the characteristics (period, duty cycle, frequency) of an

32

1 Getting Started

incoming digital signal, or count external events. Specifically, the ATmega2560 is equipped with two 8–bit timer/counters and four 16–bit timer/counters.

1.9.4.3 Pulse Width Modulation Channels A pulse width modulated or PWM signal is characterized by a fixed frequency and a varying duty cycle. Duty cycle is the percentage of time a repetitive signal is logic high during the signal period. It may be formally expressed as: dut y cycle[%] = (on time/ period) × (100%)

.

The ATmega2560 is equipped with four 8–bit pulse width modulation (PWM) channels and 12 PWM channels with programmable resolution. The PWM channels coupled with the flexibility of dividing the time base down to different PWM subsystem clock source frequencies allow the user to generate a wide variety of PWM signals: from relatively high frequency low duty cycle signals to relatively low frequency high duty cycle signals. PWM signals are used in a wide variety of applications including controlling the position of a servo motor and controlling the speed of a DC motor.

1.9.4.4 ATmega2560 Serial Communications The ATmega2560 is equipped with a host of different serial communication subsystems including the Universal Synchronous and Asynchronous Serial Receiver and Transmitter (USART), the serial peripheral interface (SPI), and the Two–wire Serial Interface. What all of these systems have in common is the serial transmission of data. In a serial communications transmission, serial data is sent a single bit at a time from transmitter to receiver. ATmega2560 Serial USART The serial USART may be used for full duplex (two way) communication between a receiver and transmitter. This is accomplished by equipping the ATmega2560 with independent hardware for the transmitter and receiver. The USART is typically used for asynchronous communication. That is, there is not a common clock between the transmitter and receiver to keep them synchronized with one another. To maintain synchronization between the transmitter and receiver, framing start and stop bits are used at the beginning and end of each data byte in a transmission sequence. The ATmega2560 USART is quite flexible. It has the capability to be set to a variety of data transmission rates known as the Baud (bits per second) rate. The USART may also be set for data bit widths of 5 to 9 bits with one or two stop bits. Furthermore, the ATmega2560 is equipped with a hardware generated parity bit (even or odd) and parity check hardware at the receiver. A single parity bit allows for the detection of a single bit error within a byte of data. The USART may also be configured to operate in a synchronous mode. ATmega2560 Serial Peripheral Interface–SPI The ATmega2560 Serial Peripheral Interface (SPI) can also be used for two–way serial communication between a transmitter and a

1.9

Arduino Mega 2560 Host Processor–the ATmega2560

33

receiver. In the SPI system, the transmitter and receiver share a common clock source. This requires an additional clock line between the transmitter and receiver but allows for higher data transmission rates as compared to the USART. The SPI may be viewed as a synchronous 16–bit shift register with an 8–bit half residing in the transmitter and the other 8–bit half residing in the receiver. The transmitter is designated the master since it is providing the synchronizing clock source between the transmitter and the receiver. The receiver is designated as the slave. ATmega2560 Two–wire Serial Interface–TWI The TWI subsystem allows the system designer to network related devices (microcontrollers, transducers, displays, memory storage, etc.) together into a system using a two–wire interconnecting scheme. The TWI allows a maximum of 128 devices to be interconnected together. Each device has its own unique address and may both transmit and receive over the two–wire bus at frequencies up to 400 kHz. This allows the device to freely exchange information with other devices in the network within a small area.

1.9.4.5 ATmega2560 Analog to Digital Converter–ADC The ATmega2560 is equipped with a 16–channel analog to digital converter (ADC) subsystem. The ADC converts an analog signal from the outside world into a binary representation suitable for use by the microcontroller. The ATmega2560 ADC has 10–bit resolution. This means that an analog voltage between 0 and 5 V will be encoded into one of 1024 binary representations between .(000)16 and .(3F F)16 . This provides the ATmega2560 with a voltage resolution of approximately 4.88 mV.

1.9.4.6 ATmega2560 Interrupts The normal execution of a program follows a designated sequence of instructions. However, sometimes this normal sequence of events must be interrupted to respond to high priority faults and status both inside and outside the microcontroller. When these higher priority events occur, the microcontroller suspends normal operation and executes event specific actions contained within an interrupt service routine (ISR). Once the higher priority event has been serviced via the ISR, the microcontroller returns and continues processing the normal program. The ATmega2560 is equipped with a complement of 57 interrupt sources. Eight interrupts are provided for external interrupt sources. Also, the ATmega2560 is equipped with three pin change interrupts. The remaining interrupts support the efficient operation of peripheral subsystems aboard the microcontroller.

34

1.10

1 Getting Started

Arduino Mega 2560 Open Source Schematic

The entire line of Arduino products is based on the visionary concept of open source hardware and software. That is, hardware and software developments are openly shared among users to stimulate new ideas and advance the Arduino concept. In keeping with the Arduino concept, the Arduino team openly shares the schematic of the Arduino Mega 2560 processing board. It is available for download at www.arduino.cc.

1.11

LilyPad Arduino

The LilyPad Arduino was developed by Dr. Leah Buechley, Ph.D. for use in wearable electronic fashions (e–textiles). The LilyPad may be sewn into clothing. Its complement of support hardware such as a power supply and input and output devices are connected to the LilyPad via conductive thread. Dr. Buechley has written several books about this fascinating synergy between electronics and the fashion world. “Sew Electric–A Collection of DIY Projects that Combine Fabric, Electronics, and Programming” co–written by Buechley, Kanjun Qiu, and Sonja de Boer provide a number of LilyPad based do it yourself (DIY) projects.

1.11.1 LilyPad Processor A wearable LilyPad processor is available in several different configurations. The LilyPad Arduino Main Board featured here hosts an Microchip ATmega328 processor shown in Fig. 1.19. Note the use of a USB 2 serial converter and an USB 2 cable (Type A male to mini type B female) to connect to the host PC. This is the same processor onboard the UNO R3. The LilyPad mainboard operates at 8 MHz and is equipped with 14 general purpose input/output pins, six PWM pins, and six analog input/output pins. The LilyPad pinout and schematic are shown in Fig. 1.20.

1.12

Extending the Hardware Features of the Arduino Platforms

Additional features and external hardware may be added to selected Arduino platforms by using a daughter card concept. The daughter card is called an Arduino Shield as shown in Fig. 1.21. The shield mates with the header pins on the Arduino board. The shield provides a small fabrication area, a processor reset button, and a general use pushbutton and two light emitting diodes (LEDs). A large number of shields have been developed to provide extended specific features (e.g. motor control, communications, etc.) for the Arduino boards.

1.13

Application: SD Card with Real Time Clock and TFT Display

35

Fig. 1.19 LilyPad Arduino with USB 2 serial converter (Figure adapted and used with permission of Arduino Team (CC BY–NC–SA) (www.arduino.cc))

1.13

Application: SD Card with Real Time Clock and TFT Display

At the end of each chapter we provide an Application section to further explore specific concepts. In this application section we first investigate the use of an SD card to provide a “hard drive” for data logging and storage for the ATmega2560 microcontroller.2 We then explore using a TFT style graphic display for illustrating data. Both the SD card and the TFT display are interfaced to the ATmega2560 via the Serial Peripheral Interface (SPI) introduced earlier in the chapter. We then develop the “BioMedVue” data logger and display. We use this device throughout the remainder of the book in a variety of applications.

1.13.1 Overview We use Adafruit’s Data Logger with a Real Time Clock (RTC) Shield (Adafruit #1141). SD cards ranging in capacity 32 MB to 32 GB may be used. We connect a 4 GB SD card [5]. We connect the SD card and RTC shield to the ATmega2560 using the Serial Peripheral Interface (SPI) subsystem. The SPI allows the attachment of peripheral devices (e.g. an SD card) to extend the features of a microcontroller. The SPI requires four connections (MOSI, MISO, CLK, and CS) between the microcontroller and the peripheral device. Several peripheral devices may be connected to the microcontroller simultaneously via the SPI; however, each device requires a separate chip select (CS) pin. We discuss the SPI subsystem in some detail in the next chapter. 2 This material may also be used for the Arduino UNO R3.

36

1 Getting Started 30/PD0/RXD 31/PD1/TXD

28/PC5/ADC5/SCL 27/PC4/ADC4/SDA

32/PD2/INT0

26/PC3/ADC3

1/PD3/INT1/OC2B

25/PC2/ADC2

2/PD4/T0/XCK

24/PC1/ADC1

ground

23/PC0/ADC0

5 VDC

17/PB5/SCK

9/PD5/T1/OC02

16/PB4/MISO

10/PD6/AIN0/OC0A

15/PB3/MOSI/OC2

11/PD7/AIN1

14/PB2/OC1B

12/PB0/CLK0/ICP1 13/PB1/OC1A

(a) LilyPad Arduino pinout

(b) LilyPad Arduino schematic Fig. 1.20 LilyPad Arduino schematic (Figure adapted and used with permission of Arduino Team (CC BY–NC–SA) (www.arduino.cc))

1.13

Application: SD Card with Real Time Clock and TFT Display

37

Fig. 1.21 Arduino shield. (Used with permission from SparkFun Electronics (CC BY–NC–SA))

We explore the Real Time Clock features next. The RTC provides the ATmega2560 the ability to track and log real time (i.e. time and date data) during data collection activities. The RTC uses the PCF8523 chip to generate real time data. We use the SPI subsystem to also connect a TFT display to the ATmega2560. We investigate the Adafruit ILI9341 full color TFT display. This display has a 2.8 in. diagonal dimension and features 240 by 320 pixel resolution with 18–bit color. The display is available in a fully configured Arduino compatible shield. As an example, we store heart arrythmia patterns in the ATmega2560 memory and display them on the TFT display.

1.13.2 SD Card with RTC We use the Adafruit Data Logger Shield (Adafruit #1141) shown in Fig. 1.22. The shield provides multiple Gigabits of additional microcontroller data storage. It features a Real Time Clock (RTC) with battery backup to timestamp collected data. RTC features provide the microcontroller the ability to track calendar time based on seconds, minutes, hours, etc. [www.adafruit.com]. To begin, the Adafruit SD card and RTC Libraries are downloaded using the Library Manager within the Arduino IDE. The SD card shield is assembled using instructions provided within “Adafruit Ultimate GPS Logger Shield.” The document is accessible via the Adafruit website (www.adafruit.com). Assemble the shield using stacking headers to allow simultaneous use of several shields (e.g. SD logger with TFT display). Equip the shield with an SD card formatted with the FAT 16 or FAT 32 file system. The SD card may be formatted using a laptop or PC with an SD card portal. Finally, equip the RTC with a CR1220 3V Lithium battery.

38

1 Getting Started

Fig. 1.22 Adafruit SD card shield. Used with permission of Adafruit (www.adafruit.com)

With the SD card and RTC libraries downloaded the shield may be tested. Ensure the shield is properly seated on the Arduino ATmega2560. To verify SD card operation, compile and upload the “CardInfo” sketch. Note the chip select (CS) pin designation must be changed from the default value of “4” to “10” in the sketch to match the configuration from the SD card shield (SD.begin(10)). The sketch verifies proper connection between the Arduino ATmega2560 and the SD card. Next, compile and upload the “ReadWrite.” This sketch provides a good template on how to write and read data from the SD card. //**************************************************************** //ReadWrite: SD card read/write // //This example shows how to read and write data to and from an //SD card file. The SD card is attached to SPI bus as follows: // - MOSI - pin 11 // - MISO - pin 12 // - CLK - pin 13 // - CS - pin 10 - Changed to pin 10 for the SD card data logger // //created: Nov 2010 by David A. Mellis //modified: Apr 2012 by Tom Igoe // //This example code is in the public domain. //***************************************************************** #include #include

1.13

Application: SD Card with Real Time Clock and TFT Display

File myFile; void setup() { //Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. } Serial.print("Initializing SD card..."); if(!SD.begin(10)) //changed to pin for Adafruit SD card logger { Serial.println("initialization failed!"); while (1); } Serial.println("initialization done."); //open the file. note that only one file can be open at a time, //so you have to close this one before opening another. myFile = SD.open("test.txt", FILE_WRITE); //if the file opened okay, write to it: if(myFile) { Serial.print("Writing to test.txt..."); myFile.println("testing 1, 2, 3."); //close the file: myFile.close(); Serial.println("done."); } else { //if the file didn’t open, print an error: Serial.println("error opening test.txt"); } //re-open the file for reading: myFile = SD.open("test.txt"); if(myFile) { Serial.println("test.txt:"); //read from the file until there’s nothing else in it: while(myFile.available())

39

40

1 Getting Started { Serial. Write(myFile.read()); } //close the file: myFile.close(); } else { //if the file didn’t open, print an error: Serial.println("error opening test.txt"); }

} void loop() { //nothing happens after setup } //*****************************************************************

Note the use of the following commands from the SD Library in the “ReadWrite” sketch: File myFile; myFile = SD.open("test.txt", FILE_WRITE); myFile.println("testing 1, 2, 3."); myFile.close(); myFile.available() myFile.read()

//provides file handle //provides access to SD card //writes to SD card //closes access to SD card //check for available bytes //reads SD card

The Adafruit Data Logger Shield is also equipped with a PCF8523 Real Time Clock. The RTC allows data to be tagged with the current date and time for later analysis. The RTC must be equipped with the CR1220 3V Lithium battery to maintain clock time when the microcontroller is without power. The RTC may be tested using the PCF8523 sketch located in the Adafruit RTClib.

1.13.3 TFT Display In previous volumes of this Arduino series we have used Liquid Crystal Displays (LCDs) to report microcontroller status, sensor output, etc. In this section we explore TFT displays which provide great flexibility in displaying graphics, text, sensor readings, etc. A TFT display consists of individually addressable picture elements (pixels). A pixel’s location is specified with an X,Y coordinate as shown in Fig. 1.23. The color for an individual

1.13

Application: SD Card with Real Time Clock and TFT Display

Fig. 1.23 TFT display coordinate system

41

(x,y, pixel color) 0

x

0

y

pixel is set by specifying the amount of red, green, and blue color components. Graphics, texts, and images are a collection of related pixels (Ada TFT). We explore the Adafruit ILI9341 full color TFT display. This display has a 2.8 in. diagonal dimension and features 240 by 320 pixel resolution with 18–bit color. The display is available in a fully configured Arduino UNO R3 (and ATmega2560) compatible shield. The communication between the Arduino and the display is via a Serial Peripheral Interface (SPI) employing Arduino pins 9 through 13. There are several application libraries available for the TFT display (Ada TFT 2020). The libraries are downloaded using the Arduino Library Manager.

1.13.4 BioMedVue–Heart Arrhythmia Displays In my senior year of college (many years ago), I developed a heart arrhythmia simulator as a capstone project. The purpose of the project was to develop a circuit to display eight different arrhythmias on a cardiac monitor [3]. Each cardiac signal was decomposed into a series of 128 data points as shown in Fig. 1.24. The data points were stored in EPROM memory in hexadecimal format. When accessed for

42

1 Getting Started 0 ...

127

full scale (0xFF)

half scale (0x80)

quarter scale (0x40)

zero (0x00)

waveform digitization

BioMedVue

x

0 0

y

BioMedVue

Fig. 1.24 BioMedVue from Adafruit TFT card shield

display, each individual data point was recalled from EPROM, passed through a digital–to–analog converter, low passed filtered, and displayed on a monitor. To demonstrate the features of the TFT display, we reconstruct the senior design project from 40+ years ago. In this example we use the Adafruit ILI9341 full color TFT display to implement the “BioMedVue” monitor. The arrhythmia data points are stored in a large array. Individual data points are read from the array and sequentially displayed on the TFT display.

1.13

Application: SD Card with Real Time Clock and TFT Display

//******************************************************************* //BioMedVue //Adapted from Adafruit GFX example //Written by Limor Fried/Ladyada for Adafruit Industries. //MIT license, all text above must be included in any redistribution //Adapted by: S. Barrett, Oct 30, 2022. //******************************************************************* #include "SPI.h" #include "Adafruit_GFX.h" #include "Adafruit_ILI9341.h" #include #define TFT_DC 9 #define TFT_CS 10

//Adafruit shield defaults

const unsigned int arrhymthmias [8][16] = {//begin 2D array //Normal Sinus Rhythm {0x84, 0x8A, 0x8C, 0x90, 0x8C, 0x8A, 0x84, 0xFF, 0x6C, 0x80, 0x80}, {0x80, 0x82, 0x83, 0x87, 0x8C, 0x90, 0x94, 0x85, 0x82, 0x80, 0x80}, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8C, 0x87, 0x83, 0x80}, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, {0x84, 0x8A, 0x8C, 0x90, 0x8C, 0x8A, 0x84, 0xFF, 0x6C, 0x80, 0x80}, {0x80, 0x82, 0x83, 0x87, 0x8C, 0x90, 0x94, 0x85, 0x82, 0x80, 0x80}, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8C, 0x87, 0x83, 0x80}, {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80} };//end 2D array

0x80, 0x80, 0x80, 0x80, 0x60, 0x99, 0x9C, 0x99, 0x90, 0x8A, 0x80, 0x85, 0x8A, 0x8C, 0x8E, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x99, 0x9C, 0x99, 0x90, 0x8A, 0x80, 0x85, 0x8A, 0x8C, 0x8E, 0x80, 0x80, 0x80, 0x80, 0x80,

//global variables x1, y1, x2, y2, screen_ctr_x, screen_ctr_y; width, height; num_passes = 2, num_row = 8, num_col = 16; num_p, num_r, num_c; data_point1, data_point2; //Hardware UNO SPI:#13, #12, #11 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); unsigned unsigned unsigned unsigned unsigned

int int int int int

void setup() { Serial.begin(9600); Serial.println("BioMedVue"); tft.begin(); width = tft.width(), height = tft.height(); Serial.print(F("Screen fill Serial.println(testFillScreen()); delay(500);

"));

Serial.print(F("Lines ")); Serial.println(testLines(ILI9341_GREEN)); delay(500); Serial.print(F("Text Serial.println(testText()); delay(3000);

"));

43

44

1 Getting Started

} void loop(void) { unsigned int word_counter = 0; unsigned int y_counter = 31; //starting point for waveform: (screen_ctr_x, 31) //subtract 24(10) from each value for(num_p = 0; num_p < num_passes; num_p++) { for(num_r = 0; num_r < num_row; num_r++) { for(num_c = 0; num_c < num_col; num_c++) { //read data points from EEPROM data_point1 = arrhymthmias[num_r][num_c]; if((num_c == 15)&&(num_r == 7)) data_point2 = data_point1; else if (num_c == 15) data_point2 = arrhymthmias[num_r + 1][0]; else data_point2 = arrhymthmias[num_r][num_c + 1]; Serial.print("r:"); Serial.print(num_r); Serial.print(" c:"); Serial.print(num_c); Serial.print(" dp1:"); Serial.println(data_point1); delay(10); Serial.print("x:"); Serial.print(screen_ctr_x + data_point1 - 20); Serial.print(" y:"); Serial.println(y_counter); Serial.println(" "); tft.drawLine(screen_ctr_x - 24, 30, screen_ctr_x - 24, height - 34, ILI9341_GREEN); tft.drawLine(data_point1 - 24 , y_counter, data_point2 - 24 , y_counter + 1,ILI9341_RED); //moving cursor tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x delay(20); tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x tft.drawPixel(screen_ctr_x delay(20);

-

22, 23, 24, 25, 26,

y_counter, y_counter, y_counter, y_counter, y_counter,

ILI9341_GREEN); ILI9341_GREEN); ILI9341_GREEN); ILI9341_GREEN); ILI9341_GREEN);

-

22, 23, 24, 25, 26,

y_counter, y_counter, y_counter, y_counter, y_counter,

ILI9341_BLACK); ILI9341_BLACK); ILI9341_GREEN); ILI9341_BLACK); ILI9341_BLACK);

y_counter++; } } } } //******************************************************************* unsigned long testFillScreen() { tft.fillScreen(ILI9341_BLACK); unsigned long start = micros(); tft.fillScreen(ILI9341_BLACK); yield(); return micros() - start; }

1.13

Application: SD Card with Real Time Clock and TFT Display

45

//******************************************************************* unsigned long testText() { unsigned long start = micros(); tft.setCursor(0, 0); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(1); tft.println("BioMedVue"); return micros() - start; } //******************************************************************* unsigned long testLines(uint16_t color) { unsigned long start, t; start = micros(); //calculate screen center screen_ctr_x = width/2; screen_ctr_y = height/2; //setup BioMedVue tft.drawLine(0, 30, width, 30, ILI9341_GREEN); tft.drawLine(screen_ctr_x - 24, 30, screen_ctr_x - 24, height - 34, ILI9341_GREEN); t = micros() - start; // fillScreen doesn’t count against timing yield(); return micros() - start; } //*******************************************************************

1.13.5 SD Card and TFT Display The SD card and the TFT display may be used together. If the SD card was assembled using stacking headers, the TFT display shield pins may be inserted into the SD card stacking headers. Also, the SD card and TFT display uses the same chip select (CS) pin (10). The CS pin on the SD card must be changed to a different pin (e.g. pin 8) as shown in Fig. 1.25. Also, change the CS pin in the SD card sketch (SD.begin(8)). The hardware components and the resulting BioMedVue is shown in Fig. 1.26.

1.13.6 Arrhythmia Display Investigate other cardiac arrhythmias. Develop a table listing the arrhythmias and what each indicates about the heart. Choose one and program it for display on the BioMedVue. Here is a possible list for consideration:

46

1 Getting Started - SD card by default set to pin 10 - Sever the bridge between the two CS pads on board reverse - Install a short jumper wire between CS and pin 8 as shown

Fig. 1.25 SD card CS change. (Used with permission of Adafruit (www.adafruit.com))

• • • • • • •

Sinus Tachycardia Paroxysmal Atrial Tachycardia Atrial Fibrillation Atrial Flutter Ventricular Tachycardia Junctional Rhythm Sinus Bradycardia.

1.13.7 Sine and Cosine Signal Generator Develop a sketch to generate a sine and cosine wave. Store the results to the SD card and display on the TFT display.

1.13

Application: SD Card with Real Time Clock and TFT Display

47

Fig. 1.26 BioMedVue. (Images used courtesy of Arduino (Arduino.cc) and Adafruit (www.adafruit. com)

48

1.14

1 Getting Started

Summary

The goal of this chapter was to provide a tutorial on how to begin programming. We used a top–down design approach. We began with the “big picture” of the chapter followed by an overview of the Arduino Development Environment. Throughout the chapter, we provided examples and also provided references to a number of excellent references. We then provided an overview of the Arduino concept of open source hardware. This was followed by a description of the Arduino UNO R3 processor board powered by the ATmega328. An overview of ATmega328 systems followed. This was followed by a description of the Arduino Mega 2560 R3 processor board powered by the ATmega2560 and its systems. We also reviewed the layout and features of the LilyPad Arduino. We completed the chapter with a series of applications related to capturing, logging, and displaying data.

1.15

Problems

1. Describe the steps in writing a sketch and executing it on an Arduino UNO R3 processing board. 2. What is the serial monitor feature used for in the Arduino Development Environment? 3. Describe what variables are required and returned and the basic function of the following built–in Arduino functions: Blink, Analog Input. 4. Sketch a block diagram of the ATmega328 and the ATmega2560 and its associated systems. Describe the function of each system. 5. Describe the different types of memory components within the ATmega328 and the ATmega2560. Describe applications for each memory type. 6. Describe the three different register types associated with each port. 7. How may the features of the Arduino UNO R3 be extended? The Mega 2560? 8. Prepare a table of features for different Arduino shield products. 9. Summarize the differences between the Arduino UNO R3 and Mega 2560. How would you choose between the two in a given application?

References 1. L. Ada, Adafruit Ultimate GPS Logger Shield, 2. Arduino homepage, www.arduino.cc 3. S. Barrett, Heart Arrhythmia Simulator, Senior Design Project, The University of Nebraska at Omaha, May 1, 1979. 4. P. Burgess, Adafruit GFX Graphics Library,

References

49

5. B. Earl, Adafruit 2.8” TFT Touch Shield V2–Capacitive or Resistive, www.adafruit.com, June 2020. 6. SparkFun Electronics, 6175 Longbow Drive, Suite 200, Boulder, CO 80301 (www.sparkfun.com) 7. Microchip 8-bit AVR Microcontroller with 64/128/256K Bytes In-System Programmable Flash, ATmega640/V, ATmega1280/V, 2560/V data sheet: 2549P-AVR-10/2012, Microchip Corporation, 2325 Orchard Parkway, San Jose, CA 95131.

2

Arduino Subsystems

Objectives: After reading this chapter, the reader should be able to: • Illustrate the analog–to–digital conversion process; • Assess the quality of analog–to–digital conversion using the metrics of sampling rate, quantization levels, number of bits used for encoding and dynamic range; • Program the Arduino UNO R3 processing board to perform an ADC using the built–in features of the Arduino Development Environment; • Describe the operation of a digital–to–analog converter (DAC); • Explain key timing system related terminology; • Compute the frequency and the period of a periodic signal using a microcontroller; • Describe the procedure to generate time critical output signals; • Program the Arduino UNO R3 using the built–in timer features of the Arduino Development Environment; • Describe the differences between serial and parallel communication; • Provide definitions for key serial communications terminology; • Describe the operation of the Universal Synchronous and Asynchronous Serial Receiver and Transmitter (USART); • Program the USART for basic transmission and reception; • Describe the operation of the Serial Peripheral Interface (SPI); • Program the SPI system using the built–in timer features of the Arduino Development Environment; • Describe the purpose of the Two Wire Interface (TWI); • Program the TWI system using the built–in timer features of the Arduino Development Environment; • Define the need for microcontroller interrupt capability; • Describe the general microcontroller interrupt response;

© The Author(s), under exclusive license to Springer Nature Switzerland AG 2024 S. F. Barrett, Arduino VI, Synthesis Lectures on Digital Circuits & Systems, https://doi.org/10.1007/978-3-031-47130-8_2

51

52

2 Arduino Subsystems

• Describe the ATmega328 and ATmega2560 interrupt features; and • Properly configure and program an interrupt event for the Arduino UNO R3 using built–in features of the Arduino Development Environment.

2.1

Introduction

In this chapter we review major subsystems onboard the Arduino UNO R3 and the ATmega2560. We explore the Analog–to–Digital Converter (ADC) Subsystem, the Timing Subsystem, the Serial Communications Subsystem, and the Interrupt Subsystem. For each subsystem we provide background theory, associated Arduino IDE commands, and examples.1

2.2

Analog–to–Digital Conversion (ADC) Subsystem

A microcontroller is used to process information from the natural world, use an algorithm to decide on a course of action based on the information collected, and then issue control signals to implement the decision. Since the information from the natural world, is analog or continuous in nature, and the microcontroller is a digital or discrete based processor, a method to convert an analog signal to a digital form is required. An ADC system performs this task while a digital–to–analog converter (DAC) performs the conversion in the opposite direction. We discuss both types of converters in this chapter. Most microcontrollers are equipped with an ADC subsystem; whereas, DACs must be added as an external peripheral device to the controller. In this section, we discuss the ADC process in some detail. We discuss the conversion process first, followed by a presentation of the successive–approximation hardware implementation of the process. We then review the basic features of the Arduino ADC subsystem and conclude with several illustrative code examples using the built–in features of the Arduino Development Environment. We briefly discuss the DAC process and Arduino Development Environment built–in features allowing generation of an output analog signal via pulse width modulation (PWM) techniques.

1 This chapter is condensed and adapted from Chaps. 3 through 6 of “Arduino II: Systems,” S. Barrett,

Morgan & Claypool Publishers, 2020. The information is provided courtesy of Morgan & Claypool Publishers and Springer Nature.

2.2

Analog–to–Digital Conversion (ADC) Subsystem

2.2.1

53

Sampling, Quantization and Encoding

In this subsection, we provide an abbreviated discussion of the ADC process.2 There are three important processes associated with the ADC process: sampling, quantization, and encoding. Sampling. Sampling is the process of taking “snap shots” of a signal over time. When we sample a signal, we want to sample it in an optimal fashion such that we capture the essence of the signal while minimizing the use of resources. In essence, we want to minimize the number of samples while retaining the capability to faithfully reconstruct the original signal from the samples. Intuitively, the rate of change of a signal determines the number of samples required to faithfully reconstruct the signal, provided that all adjacent samples are captured with the same sample timing intervals. Sampling is important since when we want to represent an analog signal in a digital system, such as a computer, we must use the appropriate sampling rate to capture the analog signal for a faithful representation in digital systems. Harry Nyquist from Bell Laboratory studied the sampling process and derived a criterion that determines the minimum sampling rate for a continuous analog signal. His, now famous, minimum sampling rate is known as the Nyquist sampling rate, which states that one must sample a signal at least twice as fast as the highest frequency content of the signal of interest. For example, if we are dealing with the human voice signal that contains frequency components that span from about 20 Hz to 4 kHz, the Nyquist sample theorem requires that we must sample the signal at least at 8 kHz, 8000 “snap shots” every second. Figure 2.1 illustrates various sample rates. When a signal is sampled a low pass anti–aliasing filter must be employed to insure the Nyquist sampling rate is not violated. In the example above, a low pass filter with a cutoff frequency of 4 kHz would be used before the sampling circuitry for this purpose. We discuss filters later in the text. Quantization. Now that we understand the sampling process, let’s move on to the second process of the analog–to–digital conversion, quantization. Each digital system has a number of bits it uses as the basic unit to represent data. A bit is the most basic unit where single binary information, one or zero, is represented. A nibble is made up of four bits put together. A byte is eight bits. We have avoided the discussion of the form of captured signal samples. When a signal is sampled, digital systems need some means to represent the captured samples. The quantization of a sampled signal is how the signal is represented as one of the quantization levels. Suppose you have a single bit to represent an incoming signal. You only have two different values, 0 and 1. You may say that you can distinguish only low from high. Suppose you 2 This discussion was condensed from “Microchip AVR Microcontroller Primer: Programming and

Interfacing,” S.F. Barrett and D.J. Pack, Springer Publishers, 2019. Information is used with permission.

54

2 Arduino Subsystems

fewer missed data points along the signal

many missed data points along the signal

slow sample rate

time

fast sample rate

time

111 110

11

101

10

100 011

01

010

00

time sample points described by four levels

001 000

time sample points described by eight levels

Fig. 2.1 Sampling rate

have two bits. You can represent four different levels, 00, 01, 10, and 11. What if you have three bits? You now can represent eight different levels: 000, 001, 010, 011, 100, 101, 110, and 111 as shown in Fig. 2.1. Think of it as follows. When you had two bits, you were able to represent four different levels. If we add one more bit, that bit can be one or zero, making the total possibilities eight. Similar discussion can lead us to conclude that given n bits, we have .2n unique numbers or levels one can represent. Figure 2.2 shows how n bits are used to quantize a range of values. In many digital systems, the incoming signals are voltage signals. The voltage signals are first obtained from physical signals (pressure, temperature, etc.) with the help of transducers, such as microphones, angle sensors, and infrared sensors. The voltage signals are then conditioned to map their range with the input range of a digital system, typically 0–5 V. In Fig. 2.2, n bits allow you to divide the input signal range of a digital system into .2n different quantization levels. As can be seen from the figure, the more quantization levels means the better mapping of an incoming signal to its true value. Now imagine what happens as we increase the number of bits available for the quantization levels. What happens when the available number of bits is eight? How many different

2.2

Analog–to–Digital Conversion (ADC) Subsystem

55

Fig. 2.2 Sampling, quantization, and encoding

quantization levels are available now? Yes, 256. How about 10, 12, or 14? Notice also that as the number of bits used for the quantization levels increases for a given input range the “distance” between two adjacent levels decreases accordingly. Encoding. Finally, the encoding process involves converting a quantized signal into a digital binary value. Suppose again we are using eight bits to quantize a sampled analog signal. The quantization levels are determined by the eight bits and each sampled signal is quantized as one of 256 quantization levels. Consider the two sampled signals shown in Fig. 2.2. The first sample is mapped to quantization level two and the second one is mapped to quantization level 198. Note the amount of quantization error introduced for both samples. The quantization error is inversely proportional to the number of bits used to quantize the signal. Once a sampled signal is quantized, the encoding process involves representing the quantization level with the available bits. Thus, for the first sample, the encoded sampled value is 0000_0010 (two), while the encoded sampled value for the second sample is 1100_0110 (198). As a result of the encoding process, sampled analog signals are now represented as a set of binary numbers. Thus, the encoding is the last necessary step to represent a sampled analog signal into its corresponding digital form, shown in Fig. 2.2.

56

2 Arduino Subsystems

2.2.2

Resolution and Data Rate

Resolution. Resolution is a measure used to quantize an analog signal. Resolution is nothing more than the voltage “distance” between two adjacent quantization levels discussed earlier. Suppose again we have a range of 5 V and one bit to represent an analog signal. The resolution in this case is 2.5 V, a very poor resolution. You can imagine how your TV screen will look if you only had only two levels to represent each pixel, black and white. The maximum error, called the resolution error, is 2.5 volts for the current case, 50% of the total range of the input signal. Suppose you now have four bits to represent quantization levels. The resolution now becomes 1.25 V or 25% of the input range. Suppose you have 20 bits for quantization levels. The resolution now becomes .4.77 × 10−6 V, .9.54 × 10−5 % of the total range. The discussion we presented simply illustrates that as we increase the available number of quantization levels within a fixed voltage range, the distance between adjacent levels decreases, reducing the quantization error of a sampled signal. As the number grows, the error decreases, making the representation of a sampled analog signal more accurate in the corresponding digital form. The number of bits used for the quantization is directly proportional to the resolution of a system. You now should understand the technical background when you watch high– definition television broadcasting. In general, resolution may be defined as: r esolution = (voltage span)/2b = (Vr e f

.

high

− Vr e f

low )/2

b

for the Arduino UNO R3 and the ATmega2560, the resolution is: r esolution = (5 − 0)/210 = 4.88 mV

.

Data rate. The definition of the data rate is the amount of data generated by a system per some time unit. Typically, the number of bits or the number of bytes per second is used as the data rate of a system. We just saw that the more bits we use for the quantization levels, the more accurate we can represent a sampled analog signal. Why not use the maximum number of bits current technologies can offer for all digital systems, when we convert analog signals to digital counterparts? It has to do with the cost involved. Suppose you are working for a telephone company and your switching system must accommodate 100,000 customers. For each individual phone conversation, suppose the company uses an 8 kHz sampling rate (. f s ) and you are using 10 bits for the quantization levels for each sampled signal.3 This means the voice conversation will be sampled every 125 microseconds (.Ts ) due to the reciprocal relationship between (. f s ) and (.Ts ).

3 For the sake of our discussion, we ignore the overhead involved in processing a phone call such as

multiplexing, de–multiplexing, and serial–to–parallel conversion.

2.2

Analog–to–Digital Conversion (ADC) Subsystem

57

If all customers are making out of town calls, what is the number of bits your switching system must process to accommodate all calls? The answer will be 100,000. × 8000 x 10 or eight billion bits every second! You will need some major computing power to meet the requirement for processing and storage of the data. For such reasons, when designers make decisions on the number of bits used for the quantization levels and the sampling rate, they must consider the computational burden the selection will produce on the computational capabilities of a digital system versus the required system resolution. Dynamic range. You will also encounter the term “dynamic range” when you consider finding appropriate analog–to–digital converters. The dynamic range is a measure used to describe the signal to noise ratio. The unit used for the measurement is Decibel (dB), which is the strength of a signal with respect to a reference signal. The greater the dB number, the stronger the signal is compared to a noise signal. The definition of the dynamic range is .20 log 2b where b is the number of bits used to convert analog signals to digital signals. Typically, you will find 8 to 12 bits used in commercial analog–to–digital converters, translating the dynamic range from .20 log 28 dB to .20 log 212 dB.

2.2.3

Analog–to–Digital Conversion (ADC) Process

The goal of the ADC process is to accurately represent analog signals as digital signals. Toward this end, three signal processing procedures, sampling, quantization, and encoding, previously described must be combined together. Before the ADC process takes place, we first need to convert a physical signal into an electrical signal with the help of a transducer. A transducer is an electrical and/or mechanical system that converts physical signals into electrical signals or electrical signals to physical signals. Depending on the purpose, we categorize a transducer as an input transducer or an output transducer. If the conversion is from physical to electrical, we call it an input transducer. The mouse, the keyboard, and the microphone for your personal computer all fall under this category. A camera, an infrared sensor, and a temperature sensor are also input transducers. The output transducer converts electrical signals to physical signals. The computer screen and the printer for your computer are output transducers. Speakers and electrical motors are also output transducers. Therefore, transducers play the central part for digital systems to operate in our physical world by transforming physical signals to and from electrical signals. It is important to carefully design the interface between transducers and the microcontroller to insure proper operation. A poorly designed interface could result in improper embedded system operation or failure.

58

2 Arduino Subsystems

2.2.4

Transducer Interface Design (TID) Circuit

In addition to transducers, we also need a signal conditioning circuitry before we apply the ADC. The signal conditioning circuitry is called the transducer interface. The objective of the transducer interface circuit is to scale and shift the electrical signal range to map the output of the input transducer to the input range of the analog–to–digital converter which is typically 0 to 5 VDC. We discus the TID process in Chapter 4.

2.2.5

ADC Conversion Technologies

The Arduino UNO R3 and the ATmega2560 use a successive–approximation converter technique to convert an analog sample into a 10–bit digital representation. In this section, we will discuss this type of conversion process. For a review of other converter techniques, the interested reader is referred to “Microchip AVR Microcontroller Primer: Programming and Interfacing.” In certain applications, you are required to use converter technologies external to the microcontroller. The successive–approximation technique uses a digital–to–analog converter, a controller, and a comparator to perform the ADC process. Starting from the most significant bit down to the least significant bit, the controller turns on each bit at a time and generates an analog signal, with the help of the digital–to–analog converter, to be compared with the original input analog signal. Based on the result of the comparison, the controller changes or leaves the current bit and turns on the next most significant bit. The process continues until decisions are made for all available bits. Figure 2.3 shows the architecture of this type of converter. The advantage of this technique is that the conversion time is uniform for any input, but the disadvantage of the technology is the use of complex hardware for implementation.

2.2.6

The Arduino UNO R3 and ATmega2560 ADC System

The Arduino UNO R3 and ATmega2560 Rev 3 microcontroller are equipped with a flexible and powerful ADC system. They have the following features: • • • • •

10–bit resolution ±2 least significant bit (LSB) absolute accuracy six multiplexed single ended input channels (UNO R3) sixteen multiplexed single ended input channels (ATmega2560 R3) 0 to Vcc ADC input voltage range

.

2.2

Analog–to–Digital Conversion (ADC) Subsystem

59

Fig. 2.3 Successive-approximation ADC

Let’s discuss each feature in turn. The first feature of discussion is “10–bit resolution.” Resolution is defined as: .

Resolution = (V R H − V R L )/2b

. V R H and . V R L are the ADC high and low reference voltages. Where, “b” is the number of bits available for conversion. For the Arduino processors with reference voltages of 5 VDC, 0 VDC, and 10–bits available for conversion, resolution is 4.88 mV. Absolute accuracy specified as .±2. LSB is then .±9.76 mV at this resolution. The ADC is equipped with a single successive–approximation converter. Only a single ADC channel may be converted at a given time. The input of the ADC is equipped with a multiple input analog multiplexer. The analog input voltage for conversion must be between 0 and Vcc volts. If this is not the case, external circuitry as previously discussed must be used to insure the analog input voltage is within these prescribed bounds.

2.2.7

Programming the ADC with the Arduino Development Environment

The Arduino Development Environment has the built–in function analogRead to perform an ADC conversion. The format for the analogRead function is:

60

2 Arduino Subsystems

//***************************************************** unsigned int

return_value;

return_value = analogRead(analog_pin_read);

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

The function returns an unsigned integer value from 0 to 1023, corresponding to the voltage span from 0 to 5 VDC. This yields a resolution of: .

Resolution = (V R H − V R L )/2b = 5/210 = 4.9 mV

The Arduino UNO R3 is equipped with six ADC channels (A0–A5). The ATmega2560 is equipped with 15 ADC channels (A0–A14). Both processors feature 10 bit ADC resolution. There are several other functions that may be used with the analogRead function: • analogReference(type): This function allows selection of a different reference voltage for ADC conversion. The default value of .V R H is 5 VDC. Selection of an alternate, predesignated .V R H value can refine the resolution. • map(): This function maps a value (fromValue) within a span of values (fromLow to fromHigh) to the corresponding value (toValue) within another span of values (toLow to toHigh) as shown in Fig. 2.4. • analogWrite(pin, value): The analogWrite function actually performs the digital–to– analog (DAC) conversion process using pulse width modulation (PWM) techniques. A PWM signal is generated on the specified pin. The PWM duty cycle is specified from 0% (value of 0) to 100% (value of 255). The duty cycle multiplied by the supply voltage provides the value of the effective voltage delivered from the pin as shown in Fig. 2.5. – The Arduino UNO R3 has PWM features available on pins 3, 5, 6, 9, 10, and 11. The baseline frequency is set for 490 Hz (pins 3, 9, 10, 11) and 980 Hz (pins 5, 6). – The Arduino ATmega2560 has PWM features available on pins 2–13 and 44–46. The baseline frequency is set for 490 Hz (pins 2–3, 5–12, 44–46) and 980 Hz (pins 4, 13). Example: In this example we connect a potentiometer to ADC pin A1 and display the result on the Serial Monitor.

2.2

Analog–to–Digital Conversion (ADC) Subsystem

61

fromHigh

fromValue toHigh toValue toLow

fromLow toValue = map(fromValue, fromLow, fromHigh, toLow, fromLow)

toHigh

toValue fromHigh fromValue fromLow

toLow

Fig. 2.4 The map function

Pulse Width Modulated (PWM) signal

time

Fig. 2.5 The analogWrite function. With the duty cycle set at 50% (value of 127), the effective value delivered by the pin is 2.5 VDC

62

2 Arduino Subsystems

//*********************************************************************** //ADC_test: Reads ADC value at A1, converts to voltage, displays // voltage and value on Serial Monitor every second. //*********************************************************************** int analogPin = A1; //pot wiper (middle) to pin A1 //outside pot leads to 5 VDC, ground int val = 0; //value read from A1 void setup() { Serial.begin(9600); }

//configure Serial Monitor

void loop() { val = analogRead(analogPin); //read the input pin Serial.println(val); //debug value float float_val = (float)(val)/1023.0 * 5.0; //convert to voltage Serial.print(float_val); Serial.println("V"); Serial.println(" "); delay(1000); } //***********************************************************************

Example: ADC Rain Gage. The circuit configuration using the Arduino UNO R3 processing board is provided in Fig. 2.6. The digital pins of the microcontroller are used to communicate with the LED interface circuit. The operation of the LED interface circuit is discussed in the next chapter. The sketch to implement the project requirements is provided below. As in previous examples, we define the Arduino UNO R3 pins, set them for output via the setup() function, and write the loop() function. In this example, the loop() function senses the voltage from the 10K trimmer potentiometer and illuminates a series of LEDs corresponding to the sensed voltage levels in a rain gage fashion. //**************************************************************** #define trim_pot A0 //analog input pin

#define #define #define #define #define #define #define #define

LED0 LED1 LED2 LED3 LED4 LED5 LED6 LED7

0 1 2 3 4 5 6 7

//digital output pins //LED indicators 0 - 7 //digital pin //digital pin //digital pin //digital pin //digital pin //digital pin //digital pin //digital pin

2.2

Analog–to–Digital Conversion (ADC) Subsystem

63

Vcc = 5 V 220

Vcc = 5 V

2N2222

220

10K

2N2222 10K

Vcc = 5 V 220

Vcc = 5 V

2N2222 10K

220

2N2222 10K

Vcc = 5 V 220

Vcc = 5 V

2N2222 10K

220

2N2222 10K

Vcc = 5 V 220

Vcc = 5 V

2N2222 10K

220

2N2222 10K Vcc = 5 V 10K

Fig. 2.6 ADC with rain gage level indicator

int trim_pot_reading;

//declare variable for trim pot

void setup() { pinMode(LED0, pinMode(LED1, pinMode(LED2, pinMode(LED3,

//config //config //config //config

OUTPUT); OUTPUT); OUTPUT); OUTPUT);

pin pin pin pin

0 1 2 3

for for for for

digital digital digital digital

out out out out

64

2 Arduino Subsystems pinMode(LED4, pinMode(LED5, pinMode(LED6, pinMode(LED7, }

OUTPUT); OUTPUT); OUTPUT); OUTPUT);

//config //config //config //config

pin pin pin pin

4 5 6 7

for for for for

digital digital digital digital

out out out out

void loop() { //read analog out from trim pot trim_pot_reading = analogRead(trim_pot); if(trim_pot_reading < 128) { digitalWrite(LED0, HIGH); digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); digitalWrite(LED4, LOW); digitalWrite(LED5, LOW); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); } else if(trim_pot_reading < 256) { digitalWrite(LED0, HIGH); digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); digitalWrite(LED4, LOW); digitalWrite(LED5, LOW); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); } else if(trim_pot_reading < 384) { digitalWrite(LED0, HIGH); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, LOW); digitalWrite(LED4, LOW); digitalWrite(LED5, LOW); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); } else if(trim_pot_reading < 512) { digitalWrite(LED0, HIGH); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); digitalWrite(LED4, LOW); digitalWrite(LED5, LOW); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); } else if(trim_pot_reading < 640) { digitalWrite(LED0, HIGH); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); digitalWrite(LED4, HIGH); digitalWrite(LED5, LOW); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); } else if(trim_pot_reading < 768) { digitalWrite(LED0, HIGH); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); digitalWrite(LED4, HIGH); digitalWrite(LED5, HIGH); digitalWrite(LED6, LOW); digitalWrite(LED7, LOW); }

2.2

Analog–to–Digital Conversion (ADC) Subsystem

else if(trim_pot_reading < 896) { digitalWrite(LED0, HIGH); digitalWrite(LED1, digitalWrite(LED2, HIGH); digitalWrite(LED3, digitalWrite(LED4, HIGH); digitalWrite(LED5, digitalWrite(LED6, HIGH); digitalWrite(LED7, } else { digitalWrite(LED0, HIGH); digitalWrite(LED1, digitalWrite(LED2, HIGH); digitalWrite(LED3, digitalWrite(LED4, HIGH); digitalWrite(LED5, digitalWrite(LED6, HIGH); digitalWrite(LED7, } delay(500); //delay 500 ms }

65

HIGH); HIGH); HIGH); LOW);

HIGH); HIGH); HIGH); HIGH);

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

2.2.8

One–Bit ADC– Threshold Detector

A threshold detector circuit or comparator configuration contains an operational amplifier employed in the open loop configuration. That is, no feedback is provided from the output back to the input to limit gain. A threshold level is applied to one input of the op amp. This serves as a comparison reference for the signal applied to the other input. The two inputs are constantly compared to one another. When the input signal is greater than the set threshold value, the op amp will saturate to a value slightly less than +Vcc as shown in Fig. 2.7a. When the input signal falls below the threshold the op amp will saturate at a voltage slightly greater than Vcc. If a single–sided op amp is used in the circuit (e.g., LM324), the Vcc supply pin may be connected to ground. In this configuration, the op map provides for a one–bit ADC circuit. A bank of threshold detectors may be used to construct a multi–channel threshold detector as shown in Fig. 2.7c. This provides a flash converter type ADC. It is a hardware version of a rain gage indicator. A 14–channel version for use in a laboratory instrumentation project is provided in a later chapter.

2.2.9

Digital–to–Analog Conversion (DAC)

Once a signal is acquired to a digital system with the help of the analog–to digital conversion process and has been processed, frequently the processed signal is converted back to another analog signal. A simple example of such a conversion occurs in digital audio processing. Human voice is converted to a digital signal, modified, processed, and converted back to an analog signal

66

2 Arduino Subsystems

Vo Vcc

+Vcc= 5 V Vp

Vi +Vcc

Vn

+

Vout

-

saturation

Vi > Vth saturation

Vi Vth

Vth

(b) Transfer characteristic for threshold detector

(a) Threshold detector +5 VDC

voltage level for comparison

+5 VDC

10K

(4)

4/5 supply

+5 VDC

(2) (1) (3)

10K

(11)

220

small LED 3/5 supply

(6)

(7)

(5) 220

10K

small LED 2/5 supply

(9) (8) (10)

10K

220

small LED 1/5 supply

(13) (14) (12) 220

10K

small LED

threshold detectors

(c) 4-channel threshold detector Fig. 2.7 One–bit ADC threshold detector

for people to hear. The process to convert digital signals to analog signals is completed by a digital–to–analog converter. The most commonly used technique to convert digital signals to analog signals is the summation method shown in Fig. 2.8. With the summation method of digital–to–analog conversion, a digital signal, represented by a set of ones and zeros, enters the digital–to–analog converter from the most significant bit to the least significant bit. For each bit, a comparator checks its logic state, high or low, to produce a clean digital bit, represented by a voltage level. Typically, in a microcontroller context, the voltage level is +5 or 0 volts to represent logic one or logic zero, respectively.

2.2

Analog–to–Digital Conversion (ADC) Subsystem

67

Fig. 2.8 A summation method to convert a digital signal into a quantized analog signal. Comparators are used to clean up incoming signals and the resulting values are multiplied by a scalar multiplier and the results are added to generate the output signal. For the final analog signal, the quantized analog signal should be connected to a low pass filter followed by a transducer interface circuit

The voltage is then multiplied by a scalar value based on its significant position of the digital signal as shown in Fig. 2.8. Once all bits for the signal have been processed, the resulting voltage levels are summed together to produce the final analog voltage value. Notice that the production of a desired analog signal may involve further signal conditioning such as a low pass filter to “smooth” the quantized analog signal and a transducer interface circuit to match the output of the digital–to–analog converter to the input of an output transducer.

2.2.10 DAC with the Arduino Development Environment As earlier discussed, the analogWrite command within the Arduino Development Environment issues a signal from 0 to 5 VDC by sending a constant from 0 to 255 using pulse width modulation (PWM) techniques. This signal, when properly filtered, serves as a DC signal. The form of the analogWrite command is the following: analogWrite(output pin, value);

68

2 Arduino Subsystems

2.2.11 DAC with External Converters A microcontroller can be equipped with a wide variety of DAC configurations including: • Single channel, 8–bit DAC connected via a parallel port (e.g., Motorola MC1408P8, Texas Instruments DAC0808) • Quad channel, 8–bit DAC connected via a parallel port (e.g., Analog Devices AD7305) • Quad channel, 8–bit DAC connected via the SPI (e.g., Analog Devices AD7304) • Octal channel, 8–bit DAC connected via the SPI (e.g., Texas Instrument TLC5628)

2.3

Timing Subsystem

One of the most important reasons for using microcontrollers is their capability to perform time related tasks. In a simple application, one can program a microcontroller to turn on or turn off an external device at a specific time. In a more involved application, we can use a microcontroller to generate complex digital waveforms with varying pulse widths to control the speed of a DC motor. In this section, we review the capabilities of the Arduino UNO R3 and the ATmega2560 R3 to perform time related functions. We begin with a review of timing related terminology. We then provide an overview of the general operation of a timing system followed by the Arduino timing system features.

2.3.1

Timing Related Terminology

In this section, we review timing related terminology including frequency, period, and duty cycle.

2.3.1.1 Frequency Consider signal.x(t) that repeats itself. We call this signal periodic with period T, if it satisfies the following equation: .

x(t) = x(t + T ).

To measure the frequency of a periodic signal, we count the number of times a particular event repeats within a one second period. The unit of frequency is the Hertz or cycles per second. For example, a sinusoidal signal with a 60 Hz frequency means that a full cycle of a sinusoid signal repeats itself 60 times each second or every 16.67 ms.

2.3 Timing Subsystem

69

2.3.1.2 Period The reciprocal of frequency is the period of a waveform. If an event occurs with a rate of 1 Hz, the period of that event is 1 s. To find the signal period (T), given the signal’s frequency (f), we simply need to apply their inverse relationship . f = T1 . Both the period and frequency of a signal are often used to specify timing constraints of microcontroller–based systems. For example, when your car is on a wintery road and slipping, the engineers who designed your car configured the anti–slippage unit to react within some millisecond period, say 20 milliseconds. The constraint then requires the monitoring system to check slippage at a rate of 50 Hz or 50 times per second.

2.3.1.3 Duty Cycle In many applications, periodic pulses are used as control signals. A good example is the use of a periodic pulse to control a servo motor. To control the direction and sometimes the speed of a motor, a periodic pulse signal with a changing duty cycle over time is used. The periodic pulse signal shown in Fig. 2.9a is on for 50 percent of the signal period and off for the rest of the period. The pulse shown in (b) is on for only 25% of the same period as the signal in (a) and off for 75 percent of the period. The duty cycle is defined as the percentage of the period a signal is on or logic high. Therefore, we refer to the signal in Fig. 2.9a as a periodic pulse signal with a 50 percent duty cycle and the corresponding signal in (b), a periodic pulse signal with a 25% duty cycle.

50 %

100 % (a)

25 %

100 % (b) Fig. 2.9 Two signals with the same period but different duty cycles. The top figure a shows a periodic signal with a 50% duty cycle and the lower figure b displays a periodic signal with a 25% duty cycle

70

2.3.2

2 Arduino Subsystems

Timing System Overview

The heart of the timing system is the time base. The time base’s frequency is used to generate a stable baseline clock signal. The Arduino UNO R3 and the ATmega2560 R3 processing board is equipped with a 16 MHz crystal oscillator time base.

2.3.3

Programming the Arduino Using the Built–in Timing Features

The Arduino Development Environment has several built–in timing features. These include: • delay(unsigned long): The delay function pauses a sketch for the amount of time specified in milliseconds. • delayMicroseconds(unsigned int): The delayMicroseconds function pauses a sketch for the amount of time specified in microseconds. • pulseIn(pin, value): The pulseIn function measures the length of an incoming digital pulse. If value is specified as HIGH, the function waits for the specified pin to go high and then times until the pin goes low. The pulseIn function returns the length of elapsed time in microseconds as an unsigned long. • analogWrite(pin, value): The analog write function provides a pulse width modulated (PWM) output signal on the specified pin. The PWM frequency is approximately 490 Hz. The duty cycle is specified from 0 (value of 0) to 100 (value of 255) percent. Example: In this example we connect a potentiometer to the A1 ADC pin and display the result on the Serial Monitor. We also use the ADC value to modulate the intensity of the built–in LED. Note the use of the map function to map the ADC value (0 to 1023) to the values needed by the analogWrite function (0 to 255). //*********************************************************************** //ADC_DAC_test: Reads ADC value at A1, converts to voltage, displays //voltage and value on Serial Monitor every second. Map ADC value (0-255) //to analogWrite value (0 - 1023) to modulate intensity of internal LED. //*********************************************************************** #define int_LED 13

//name pin 13 int_LED

int analogPin = A1;

//pot wiper (middle) to pin A1 //outside pot leads to 5 VDC, ground //value read from A1

int val = 0; void setup() { Serial.begin(9600); }

//configure Serial Monitor

2.4

Serial Communications

71

void loop() { val = analogRead(analogPin); //read the input pin Serial.println(val); //debug value float float_val = (float)(val)/1023.0 * 5.0; //convert to voltage Serial.print(float_val); Serial.println("V"); Serial.println(" "); val = map(val, 0, 1023, 0, 255); //map ADC value to analogWrite val analogWrite(int_LED, val); //modulate int int_LED delay(100); } //***********************************************************************

2.4

Serial Communications

Microcontrollers must often exchange data with other microcontrollers or peripheral devices. Data may be exchanged by using parallel or serial techniques. With parallel techniques, an entire byte of data is typically sent simultaneously from the transmitting device to the receiver device. While this is efficient from a time point of view, it requires eight separate lines for the data transfer.4 In serial transmission, a byte of data is sent a single bit at a time. Once eight bits have been received at the receiver, the data byte is reconstructed. While this is inefficient from a time point of view, it only requires a line (or two) to transmit the data. The Arduino UNO R3 and ATmega2560 R3 are equipped with a host of different serial communication subsystems including the serial USART, the serial peripheral interface or SPI, and the Two–wire Serial Interface (TWI). What all of these systems have in common is the serial transmission of data. Before discussing the different serial communication features aboard these processors, we review serial communication terminology.

2.4.1

Serial Communication Terminology

In this section, we review common terminology associated with serial communication. Asynchronous versus Synchronous Serial Transmission: In serial communications, the transmitting and receiving device must be synchronized to one another and use a common data rate and protocol. Synchronization allows both the transmitter and receiver to be expecting data transmission/reception at the same time. There are two basic methods of maintaining “sync” between the transmitter and receiver: asynchronous and synchronous. 4 The sections on serial communication theory were adapted with permission from “Microcontroller

Fundamentals for Engineers and Scientists,” S.F. Barrett and D.J. Pack, Morgan and Claypool Publishers, 2006.

72

2 Arduino Subsystems

In an asynchronous serial communication system, such as the USART, framing bits are used at the beginning and end of a data byte. These framing bits alert the receiver that an incoming data byte has arrived and also signals the completion of the data byte reception. The data rate for an asynchronous serial system is typically much slower than the synchronous system, but it only requires a single data line and common ground between the transmitter and receiver. A synchronous serial communication system maintains “sync” between the transmitter and receiver by employing a common clock between the two devices. Data bits are sent and received on the edge of the clock. This allows data transfer rates higher than with asynchronous techniques but requires two lines, data and clock, to connect the receiver and transmitter. Also, a common ground between the transmitter and receiver is required. Baud rate: Data transmission rates are typically specified as a Baud or bits per second rate. For example, 9600 Baud indicates the data is being transferred at 9600 bits per second. Full Duplex: Often serial communication systems must both transmit and receive data. To do both transmission and reception, simultaneously, requires separate hardware for transmission and reception. A single duplex system has a single complement of hardware that must be switched from transmission to reception configuration. A full duplex serial communication system has separate hardware for transmission and reception. Non–return to Zero (NRZ) Coding Format: There are many different coding standards used within serial communications. The important point is the transmitter and receiver must use a common coding standard so data may be interpreted correctly at the receiving end. The Arduino UNO R3 and the ATmega2560 R3 use a non–return to zero (NRZ) coding standard. In NRZ coding a logic one is signaled by a logic high during the entire time slot allocated for a single bit; whereas, a logic zero is signaled by a logic low during the entire time slot allocated for a single bit. The RS–232 Communication Protocol: When serial transmission occurs over a long distance additional techniques may be used to insure data integrity. Over long distances logic levels degrade and may be corrupted by noise. At the receiving end, it is difficult to discern a logic high from a logic low. The RS–232 standard has been around for some time. With the RS–232 standard (EIA–232), a logic one is represented with a –12 VDC level while a logic zero is represented by a +12 VDC level. Chips are commonly available (e.g., MAX232) that convert the 5 and 0 V output levels from a transmitter to RS–232 compatible levels and convert back to 5V and 0 V levels at the receiver. The RS–232 standard also specifies other features for this communication protocol. Parity: To further enhance data integrity during transmission, parity techniques may be used. Parity is an additional bit (or bits) that may be transmitted with the data byte. The Arduino UNO R3 and ATmega2560 R3 employs a single parity bit. With a single parity bit, a single bit error may be detected. Parity may be even or odd. In even parity, the parity bit is set to one or zero such that the number of ones in the data byte including the parity bit is even. In odd parity, the parity bit is set to one or zero such that the number of ones in the data byte including the parity bit is odd. At the receiver, the

2.4

Serial Communications

73

Least significant digit

Most significant digit

0x_0 0x_1 0x_2 0x_3 0x_4 0x_5 0x_6 0x_7 0x_8 0x_9 0x_A 0x_B 0x_C 0x_D 0x_E 0x_F

0x0_

0x1_

0x2_

0x3_

0x4_

0x5_

0x6_

0x7_

NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

SP ! “ # $ % & ‘ ( ) * + ‘ . /

0 1 2 3 4 5 6 7 8 9 : ; < = > ?

@ A B C D E F G H I J K L M N O

P Q R S T U V W X Y Z [ \ ] ^ _

` a b c d e f g h i j k l m n o

p q r s t u v w x y z { | } ~ DEL

Fig.2.10 ASCII Code. The ASCII code is used to encode alphanumeric characters. The “0x” indicates hexadecimal notation in the C programming language

number of bits within a data byte including the parity bit are counted to ensure that parity has not changed, indicating an error, during transmission. ASCII: The American Standard Code for Information Interchange or ASCII is a standardized, seven bit method of encoding alphanumeric data. It has been in use for many decades, so some of the characters and actions listed in the ASCII table are not in common use today. However, ASCII is still the most common method of encoding alphanumeric data. The ASCII code is provided in Fig. 2.10. For example, the capital letter “G” is encoded in ASCII as 0. × 47. The “0x” symbol indicates the hexadecimal number representation. Unicode is the international counterpart of ASCII. It provides standardized 16–bit encoding format for the written languages of the world. ASCII is a subset of Unicode. The interested reader is referred to the Unicode home page website, www.unicode.org, for additional information on this standardized encoding format.

2.4.2

Serial USART

The serial USART (or Universal Synchronous and Asynchronous Serial Receiver and Transmitter) provide for full duplex (two way) communication between a receiver and transmitter. This is accomplished by equipping the Arduino with independent hardware for the transmitter and receiver.

74

2 Arduino Subsystems

The Arduino UNO R3 is equipped with a single USART channel; whereas, the ATmega2560 is equipped with four USART channels.5 The USART is typically used for asynchronous communication. That is, there is not a common clock between the transmitter and receiver to keep them synchronized with one another. To maintain synchronization between the transmitter and receiver, framing start and stop bits are used at the beginning and end of each data byte in a transmission sequence. The Microchip USART also has synchronous features. Space does not permit a discussion of these USART enhancements. The USART is quite flexible. It has the capability to be set to a variety of data transmission or Baud (bits per second) rates. The USART may also be set for data bit widths of 5 to 9 bits with one or two stop bits. Furthermore, the USART is equipped with a hardware generated parity bit (even or odd) and parity check hardware at the receiver. A single parity bit allows for the detection of a single bit error within a byte of data. The USART may also be configured to operate in a synchronous mode. We now discuss the operation, programming, and application of the USART. Due to space limitations, we cover only the most basic capability of this flexible and powerful serial communication system.

2.4.3

USART Programming with the ADE–Serial LCD

An LCD is an output device to display text information . LCDs come in a wide variety of configurations including multi–character, multi–line format. A 16. × 2 LCD format is common. That is, it has the capability of displaying two lines of 16 characters each. Each display character and line has a specific associated address. The characters are sent to the LCD via American Standard Code for Information Interchange (ASCII) format a single character at a time. For a parallel configured LCD, an eight bit data path and two lines are required between the microcontroller and the LCD. Many parallel configured LCDs may also be configured for a four–bit data path thus saving several precious microcontroller pins. A small microcontroller mounted to the back panel of the LCD translates the ASCII data characters and control signals to properly display the characters. To conserve precious, limited microcontroller input/output pins, a serial configured LCD may be used. A serial LCD reduces the number of required microcontroller pins for interface, from ten down to one, as shown in Fig. 2.11. Display data and control information is sent to the LCD via an asynchronous UART serial communication link (8 data bits, 1 stop bit, no parity, 9600 Baud). A serial configured LCD costs slightly more than a similarly configured parallel LCD.

5 The Arduino UNO R3 USART channel is dedicated to communication between the host computer

and the Arduino platform. USART capability is provided by the Arduino Software Serial Library.

2.4

Serial Communications

75

RX 5 VDC

Sparkfun LCD-09395

Line Character Position (n) 0-15 1 64-79 2 16-31 3 80-95 4 Note: character position is specifed as 0X80 + n Command Code 0x01 0x14 0x10 0x80 + n

Command Clear Display Cursor one space right Cursor one space left Cursor to position

Note: precede command with 0xFE (25410)

Fig. 2.11 LCD serial display. (UNO R3 illustration used with permission of the Arduino Team (CC BY–NC–SA) www.arduino.cc)

Example: In this example a Sparkfun LCD–09395, 5.0 VDC, serial, 16 by 2 character, black on white LCD display is connected to the Arduino UNO R3. Communication between the UNO R3 and the LCD is accomplished by a single 9600 bits per second (BAUD) connection. Rather than use the onboard Universal Asynchronous Receiver Transmitter (UART), the Arduino Software Serial Library is used. The library provides functions to mimic UART activities on two digital pins (RX_pin, TX_pin). Details on the Library are provided at the Arduino website (www.arduino.cc). //******************************************************************* //Example uses the Arduino Software Serial Library with the //Sparkfun LCD-09395. // - provides software-based serial port //******************************************************************* #include //Specify Arduino pins for Serial connection: // SoftwareSerial LCD(RX_pin, TX_pin); SoftwareSerial LCD(10, 11); void setup() { LCD.begin(9600);

//Baud rate: 9600 Baud

76

2 Arduino Subsystems

delay(500); }

//Delay for display

void loop() { //Cursor to line one, character one LCD.write(254); //Command prefix LCD.write(128); //Command //clear display LCD.write(" LCD.write("

"); ");

//Cursor to line one, character one LCD.write(254); //Command prefix LCD.write(128); //Command LCD.write("SerLCD Test"); //Cursor to line two, character one LCD.write(254); //Command prefix LCD.write(192); //Command LCD.write("LCD-09395"); while(1); }

//pause here

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

2.5

Serial Peripheral Interface–SPI

The Serial Peripheral Interface or SPI provides for two–way serial communication between a transmitter and a receiver. In the SPI system, the transmitter and receiver share a common clock source. This requires an additional clock line between the transmitter and receiver but allows for higher data transmission rates as compared to the USART. The SPI system allows for fast and efficient data exchange between microcontrollers or peripheral devices. There are many SPI compatible external systems available to extend the features of the microcontroller. For example, a liquid crystal display or a digital–to–analog converter could be added to the microcontroller using the SPI system.

2.5.1

SPI Operation

The SPI may be viewed as a synchronous 16–bit shift register with an 8–bit half residing in the transmitter and the other 8–bit half residing in the receiver as shown in Fig. 2.12. The transmitter is designated the master since it is providing the synchronizing clock source

2.5

Serial Peripheral Interface–SPI

77

Master Device

Slave Device

SPI Data Register (SDR) MSB

MISO (PB6)

LSB

MOSI (PB5) SCK

SCK SPI Clock Generator

SPI Data Register (SDR) MSB

LSB

MOSI (PB5) system clock

MISO (PB6)

SCK (PB7)

SCK (PB7)

SS (PB4)

SS (PB4)

shift enable

SPI Status Register (SPSR) SPI Control Register (SPCR)

Fig. 2.12 SPI overview

between the transmitter and the receiver. The receiver is designated as the slave. A slave is chosen for reception by taking its Slave Select (.SS) line low. When the .SS line is taken low, the slave’s shifting capability is enabled. SPI transmission is initiated by loading a data byte into the master configured SPI Data Register (SPDR). At that time, the SPI clock generator provides clock pulses to the master and also to the slave via the SCK pin. A single bit is shifted out of the master designated shift register on the Master Out Slave In (MOSI) microcontroller pin on every SCK pulse. The data is received at the MOSI pin of the slave designated device. At the same time, a single bit is shifted out of the Master In Slave Out (MISO) pin of the slave device and into the MISO pin of the master device. After eight master SCK clock pulses, a byte of data has been exchanged between the master and slave designated SPI devices. Completion of data transmission in the master and data reception in the slave is signaled by the SPI Interrupt Flag (SPIF) in both devices. The SPIF flag is located in the SPI Status Register (SPSR) of each device. At that time, another data byte may be transmitted.

2.5.2

SPI Programming in the Arduino Development Environment

The Arduino Development Environment provides a series of SPI related functions including (www.Arduino.cc): • SPI.begin(): Initializes the SPI subsystem associated pins: setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low, and SS high. • SPISettings(speedMaximum, dataOrder, dataMode):

78

2 Arduino Subsystems

– speedMaximum: Defines the maximum speed of SPI communication. This speed is usually determined by the peripheral device. For a data rate of 20 MHz, specify the speedMaximum as 20000000. – dataOrder: indicates whether the data byte will be sent most significant bit first (MSBFIRST) or least significant bit first (LSBFIRST). – dataMode: SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3. • SPI.beginTransaction(): Initializes the SPI bus using the defined SPISettings. Call the function using this format: SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode)) • SPI.endTransaction(): Call this function after de–asserting the SPI chip select pin. This function stops use of the SPI bus for a specific SPI peripheral device. Allows other SPI peripherals to use the SPI subsystem. • SPI.end(): Disables the SPI subsystem without modifying the SPI pin modes. In the next section we provide an example demonstrating how microcontroller features may be extended with the SPI system. As a first example, recall the SPI system was used in the Application section of Chap. 1 to connect the ATmega2560 to a TFT display and SD card. Please note some of the applications use the Arduino IDE SPI built–in functions while others use advanced libraries provided by the manufacturers.

2.5.3

LED Strip

Example: LED strips may be used to display the status of temperature, blood pressure, etc. for instrumentation–based applications. In this example we control an LPD8806–based LED strip using the Arduino UNO R3. We use a one meter, 32 RGB LED strip available from Adafruit (#306) for approximately $30 USD (www.adafruit.com). The red, blue, and green component of each RGB LED is independently set using an eight–bit code. The most significant bit (MSB) is logic one followed by seven bits to set the LED intensity (0 to 127). The component values are sequentially shifted out of the Arduino UNO R3 using the Serial Peripheral Interface (SPI) features. The first component value shifted out corresponds to the LED nearest the microcontroller. Each shifted component value is latched to the corresponding R, G, and B component of the LED. As a new component value is received, the previous value is latched and held constant. An extra byte is required to latch the final parameter value. A zero byte .(00)16 is used to complete the data sequence and reset back to the first LED (www.adafruit.com). Only four connections are required between the UNO R3 and the LED strip as shown in Fig. 2.13. The connections are color coded: red–power, black–ground, yellow–data, and green–clock. It is important to note the LED strip requires a supply of 5 VDC and a current

2.5

Serial Peripheral Interface–SPI

79

Fig. 2.13 UNO R3 controlling LED strip. LED strip illustration used with permission of Adafruit (www.adafruit.com). UNO R3 illustration used with permission of the Arduino Team (CC BY–NC–SA) www.arduino.cc

rating of 2 amps per meter of LED strip. In this example we use the Adafruit #276 5V 2A (2000mA) switching power supply (www.adafruit.com). In this example each RGB component is sent separately to the strip. The example illustrates how each variable in the program controls a specific aspect of the LED strip. Here are some important implementation notes: • • • •

SPI must be configured for most significant bit (MSB) first. LED brightness is seven bits. Most significant bit (MSB) must be set to logic one. Each LED requires a separate R–G–B intensity component. The order of data is G–R–B. After sending data for all LEDs. A byte of (0. × 00) must be sent to return strip to first LED. • Data stream for each LED is: 1–G6–G5–G4–G3–G2–G1–G0–1–R6–R5–R4–R3–R2– R1–R0–1–B6–B5–B4–B3–B2–B1–B0

80

2 Arduino Subsystems

//*********************************************************************** //RGB_led_strip_tutorial: illustrates different variables within //RGB LED strip // //LED strip LDP8806 - available from www.adafruit.com (#306) // //Connections: // - External 5 VDC supply - Adafruit 5 VDC, 2A (#276) - red // - Ground - black // - Serial Data In - Arduino pin 11 (MOSI pin)- yellow // - CLK Arduino pin 13 (SCK pin)- green // //Variables: // - LED_brightness - set intensity from 0 to 127 // - segment_delay - delay between LED RGB segments // - strip_delay - delay between LED strip update // //Notes: // - SPI must be configured for Most significant bit (MSB) first // - LED brightness is seven bits. Most significant bit (MSB) // must be set to logic one // - Each LED requires a separate R-G-B intensity component. The order // of data is G-R-B. // - After sending data for all strip LEDs. A byte of (0$\,\times\,$00) must // be sent to return strip to first LED. // - Data stream for each LED is: //1-G6-G5-G4-G3-G2-G1-G0-1-R6-R5-R4-R3-R2-R1-R0-1-B6-B5-B4-B3-B2-B1-B0 // //This example code is in the public domain. //******************************************************************** #include #define LED_strip_latch 0$\,\times\,$00 const byte strip_length = 32; const byte segment_delay = 100; const byte strip_delay = 500; unsigned char LED_brightness; unsigned char position; unsigned char troubleshooting = 0;

//number of RGB LEDs in strip //delay in milliseconds //delay in milliseconds //0 to 127 //LED position in strip //allows printouts to serial //monitor

void setup() { SPI.begin(); //SPI support functions SPI.setBitOrder(MSBFIRST); //SPI bit order SPI.setDataMode(SPI_MODE3); //SPI mode SPI.setClockDivider(SPI_CLOCK_DIV32);//SPI data clock rate Serial.begin(9600); //serial comm at 9600 bps } void loop() {

2.5

Serial Peripheral Interface–SPI

SPI.transfer(LED_strip_latch); clear_strip(); delay(500);

81 //reset to first segment //all strip LEDs to black

//increment the green intensity of the strip LEDs for(LED_brightness = 0; LED_brightness 50,000 -- Vo = Avol (Vp - Vn)

-Vcc

saturation

Fig. 4.1 Ideal operational amplifier characteristics Vout

5V

+5 VDC

+ Vin

V th

-

Vout

Vth

Vin

Fig. 4.2 Op amp comparator level detector circuit

between the supply voltage and ground. The input signal is provided to the other input as shown in Fig. 4.2 (Stout and Kaufman). When the input signal is higher than the threshold voltage, the op amp saturates toward the positive supply value. When the input signal is less than threshold signal, the op amp saturates toward the negative supply value. A comparator circuit may be used to restore a degraded digital signal to its original values. In this case a single–sided op amp such as the LM324 may be used with supply voltages of 5 VDC and ground for a 5 VDC digital system. An ideal operational does not exist in the real world. However, it is a good first approximation for use in developing op amp application circuits. As shown in Fig. 4.1 an op amp has the following ideal characteristics (Sedra and Smith): • • • • •

Input currents In and Ip equal to zero; Infinite input impedance; Vp and Vn input voltages equal to one another; Extremely high open loop gain; Output impedance of zero;

180

4 Operational Amplifiers and Filtering

• Infinite bandwidth; • High slew rate; and • Infinite common mode rejection. We use these ideal conditions as a close approximation when developing characteristic equations for different op amp configurations.

4.4

Nonideal Characteristics

Ideal op amps do not exist in the real world although some come close. To better understand nonideal op amp features, we explore their origins and potential compensation methods (Sedra and Smith, Faulkenberry, Stout and Kaufman). • Frequency Response: Ideally we desire an infinite bandwidth or frequency response. That is, we want the op amp to provide the same amplification response across the frequency spectrum. Due to internal capacitance and internal configurations, the frequency response usually has a lower and upper 3 dB point. A 3 dB point is a frequency where the op amp gain is down 3 dB from its passband value. In a specific application an op amp should be chosen that operates at the desired frequencies. • Gain Bandwidth Product: The Gain Bandwidth Product (GBP) is a metric that describes the tradeoff between op amp voltage gain and desired frequency of operation. The GBP is a fixed value parameter for a specific op amp. Therefore, as the desired gain is increased the corresponding bandwidth decreases and vice versa. To provide a reasonable gain and bandwidth combination, the op amp is typically used in closed loop configurations as described in the next section. • Offset Voltage: Typically an op amp consists of multiple stages. The first stage consists of a differential transistor pair with matched characteristics for the positive and negative portion of the amplifier. Any mismatch between the two input transistor characteristics is amplified. This leads to an op amp output voltage even when both inputs are at zero volts. Some op amps are equipped with offset null compensation inputs. A potentiometer may be connected between these inputs to provide an offset compensation for the mismatched inputs. • Bias Current: The differential amplifier input described above requires small bias currents to maintain the input transistors in an active state. If each of the input bias currents flow through the same equivalent resistance, they are canceled out by the differential input amplifier configuration. A compensation resistor,. R p = Ri ||R f , may be connected between the positive input lead .V p and ground to minimize this effect. The resistors . Ri and . R f are the input and feedback resistors. • Input resistance: Ideally we want the input resistance . Ri to be very high. This prevents loading down a previous op amp stage or having the current stage affect another stage’s

4.5

Configurations

181

operation. This effect can be minimized by the wise choice of . Ri values and using a voltage follower configuration between stages. The voltage follower provides no gain but provides high input impedance. We explore the voltage follower configuration in the next section. • Common Mode Rejection Ratio (CMRR): Ideally the op amp should amplify the difference between its two inputs while cancelling any voltages common to both inputs. This allows for the cancellation of noise common to both inputs. The Common Mode Rejection Ratio or CMRR is a metric comparing an op amp’s differential gain (. Ad ) to its common mode gain (. Acm ). It is expressed as: C M R R = 20 log(|Ad |/|AC M |)

.

• Slew Rate: Ideally the op amp should amplify a signal with high fidelity even for high output amplitudes rapidly changing at high frequencies. The slew rate is a parameter provided in volts per microsecond describing the op amp’s capability to do this.

4.5

Configurations

As described in previous sections, the op amp has a very large open loop gain which minimizes bandwidth and also the differential voltage applied to the inputs. Therefore, op amps are typically used in a closed loop configuration with a controlled gain to perform a variety of functions. A sample of classic operational amplifier configurations are provided in Fig. 4.3 (Faulkenberry). It should be emphasized that the equations provided with each operational amplifier circuit are only valid if the circuit configurations are identical to those shown. Even a slight variation in the circuit configuration may have a dramatic effect on circuit operation. It is important to analyze each operational amplifier circuit using the following steps: • Write the node equation at Vn for the circuit. • Apply ideal op amp characteristics to the node equation. • Solve the node equation for Vo. As an example, we provide the analysis of the noninverting amplifier circuit in Fig. 4.4. This same analysis technique may be applied to all of the circuits in Fig. 4.3 to arrive at the equations for Vout provided. A brief description of each configurations follows. • Inverting amplifier: The inverting amplifier provides a gain determined by . Av = − R f /Ri . As indicated by the minus sign, the amplifier inverts the polarity of the input signal to produce the output signal. The value of . Ri should be kept high to maintain a

182

4 Operational Amplifiers and Filtering Rf +Vcc

-

+Vcc

Ri

-

Vin

+

Vout = Vin

+

Vout = - (Rf / Ri)(Vin)

Vin

-Vcc

-Vcc

(a) Inverting amplifier

(b) Voltage follower

Rf V1

+Vcc

Ri

+Vcc

-

Vout = ((Rf + Ri)/Ri)(Vin)

+ Vin

V2

-Vcc

-Vcc

Ri

V3

R2 R3

Rf (d) Differential input amplifier

Rf

R1

Rf +Vcc

+Vcc

+ -Vcc

Vout = - (Rf / R1)(V1) - (Rf / R2)(V2) - (Rf / R3)(V3)

-

-Vcc

(f) Transimpedance amplifier (current-to-voltage converter)

Rf

Vin

Vout = - (I Rf)

+

I

(e) Scaling adder amplifier

C

Vout = (Rf/Ri)(V2 -V1)

+

(c) Non-inverting amplifier

V1 V2

Rf

Ri

C +Vcc

+Vcc

Rf

-

Vout = - Rf C (dVin/dt)

+ -Vcc

(g) Differentiator

Vin

Vout = - 1/(Rf C) (Vindt)

+ -Vcc

(h) Integrator

Fig. 4.3 Classic operational amplifier configurations. Adapted from [Faulkenberry]

high input impedance. Also, the gain should be limited to prevent saturation of the output signal. • Voltage follower: The voltage follower circuit provides a high impedance buffer for use between op amp stages in multi–stage designs. As the name implies, the output signal follows the input signal.

4.6 Transducer Interface Design (TID)

183 Node equation at Vn:

Rf

(Vn - Vin)/ Ri + (Vn - Vout)/Rf + In = 0 Vn

Ri In Vin

Ip

+Vcc

Apply ideal conditions:

Vout

+ Vp

In = Ip = 0 Vn = Vp = 0 (since Vp is grounded)

-Vcc

Solve node equation for Vout: Vout = - (Rf / Ri)(Vin)

Fig.4.4 Operational amplifier analysis for the non–inverting amplifier. Adapted from (Faulkenberry)

• Noninverting amplifier: The noninverting amplifier provides a noninverted gain. The value of . Ri should be kept high to maintain a high input impedance. Also, the gain should be limited to prevent saturation of the output signal. • Difference amplifier: The difference amplifier provides the amplified difference of its two input signals. Voltages common to both inputs are not amplified (e.g. noise). • Summing amplifier: The summing amplifier provides the amplified sum of the input signals. The input values of . Ri may be chosen to determine the relative proportions of each input signal within the output signal. Also note the signal inversion at the output. The individual value of the input resistances (. R1 , R2 , R3 ) should be kept high to maintain high input impedance. • Transimpedance amplifier: The transimpedance amplifier translates a current input to a voltage output. This configuration is commonly used to convert the current output from certain transducer to a voltage suitable for conversion by a microcontroller. • Integrator: The integrator performs the mathematical integration of the input signal. • Differentiator: The differentiator performs the mathematical integration of the input signal. For the remainder of the chapter we explore different op amp applications.

4.6

Transducer Interface Design (TID)

A transducer is used to convert a physical variable such as temperature, pressure, or light intensity to a voltage for data collection and analysis by a microcontroller. The microcontroller accepts voltages between its power supply value and ground for analog–to–digital

184

4 Operational Amplifiers and Filtering

Fig. 4.5 Signal conditioning for ADC. A block diagram of the signal conditioning for an analog–to– digital converter. The range of the sensor voltage output is mapped to the analog–to–digital converter input voltage range. The scalar multiplier maps the magnitudes of the two ranges and the bias voltage is used to align two limits

conversion. It is the responsibility of the system designer to ensure transducer outputs are properly conditioned to meet these constraints.1 The signal conditioning circuitry is called the transducer interface. The objective of the transducer interface circuit is to scale and shift the electrical signal range to efficiently map the output of the input transducer to the input range of the analog–to–digital converter which is typically 0–5 VDC or 0–3.3 VDC. Figure 4.5 shows the transducer interface circuit using an input transducer. This process assumes a linear input transducer. The output of the input transducer is first scaled by constant K. As an example, in the figure, we use a microphone as the input transducer whose output ranges from .−5 VDC to .+5 VDC. The input to the analog–to–digital converter ranges from 0 VDC to 5 VDC. The scalar multiplier with constant K maps the output range of the input transducer to the input range of the converter. Naturally, we need to multiply all input signals by .1/2 to accommodate the mapping. Once the range has been mapped, the signal now needs to be shifted. Note that the scale factor maps the output range of the input transducer as .−2.5 VDC to .+2.5 VDC instead of 0 VDC to 5 VDC. The second portion of the circuit, the bias stage, shifts the range by 2.5 VDC, thereby completing the correct mapping. Actual implementation of the circuit components are accomplished using operational amplifiers. In general, the scaling and bias process may be described by two equations: .

V2max = (V1max × K ) + B

.

V2min = (V1min × K ) + B

1 The section on transducer interface design is adapted from “Electrical Signals and Systems,” Depart-

ment of Electrical Engineering, United States Air Force Academy.

4.6 Transducer Interface Design (TID)

185

The variable .V1max represents the maximum output voltage from the input transducer. This voltage occurs when the maximum physical variable (. X max ) is presented to the input transducer. This voltage must be scaled by the scalar multiplier (K) and then a DC offset bias voltage (B) is added to provide the voltage .V2max to the input of the ADC converter. Similarly, The variable .V1min represents the minimum output voltage from the input transducer. This voltage occurs when the minimum physical variable (. X min ) is presented to the input transducer. This voltage must be scaled by the scalar multiplier (K) and then have a DC offset bias voltage (B) added to produce voltage .V2min to the input of the ADC converter. Usually, the values of .V1max and .V1min are provided with the documentation for the transducer. Also, the values of .V2max and .V2min are known. They are the high and low reference voltages for the ADC system (usually 5 VDC and 0 VDC for a microcontroller). We thus have two equations and two unknowns to solve for K and B. The circuits to scale by K and add the offset B are usually implemented with operational amplifiers. Example: A photodiode is a semiconductor device that provides an output current corresponding to the light impinging on its active surface. The photodiode is used with a transimpedance amplifier to convert the output current to an output voltage. A photodiode/transimpedance amplifier provides an output voltage of 0 volts for maximum rated light intensity and .−2.50 VDC output voltage for the minimum rated light intensity. Calculate the required values of K and B for this light transducer so it may be interfaced to a microcontroller’s ADC system. .

V2max = (V1max × K ) + B

.

V2min = (V1min × K ) + B 5.0 V = (0 V × K ) + B

.

0 V = (−2.50 V × K ) + B

.

The values of K and B may then be determined to be 2 and 5 VDC, respectively. The transducer interface circuit is then implemented using operational amplifiers (op amps). Example: It was determined that the values of K and B were 2 and 5 VDC, respectively. The two–stage op amp circuitry provided in Fig. 4.6 implements these values of K and B. The first stage provides an amplification of .−2 due to the use of the inverting amplifier configuration. In the second stage, a summing amplifier is used to add the output of the first stage with a bias of .−5 VDC. Since this stage also introduces a minus sign to the result, the overall result of a gain of 2 and a bias of .+5 VDC is achieved.

186

4 Operational Amplifiers and Filtering

Rf = 20K Rf = 10K +Vcc

Ri = 10K Vin

+Vcc

-

Ri = 10K

+

-

-Vcc -Vcc

10K

Ri = 10K bias = 5 VDC

Vout

+ -Vcc

Fig. 4.6 Operational amplifier implementation of the transducer interface design (TID) example circuit

4.7

Active Filters

A filter is commonly used to separate desired material from a combination of materials. For example, when brewing coffee, a filter is used to block coffee grounds from the desired coffee beverage. Similarly, in electronic applications a filter is used to block or reduce specific frequencies from a desired signal. For example, when measuring signals from the body, electronic filters may be used to block noise sources from the desired signal. Noise sources may result from body movement artifacts, power system noise (e.g. 60 Hz signals), or other sources. In this section we describe active filter implementation using op amps. The term active means the filter requires an external DC power source to accomplish its filtering action. We use powered op amps along with passive resistive and capacitive components to implement many different filter types. Passive filters, those not requiring a power supply, may also be implemented using inductive, capacitive, and resistive components. However, the implementation of these filters typically result in a larger physical implementation. We begin with a review of basic filter concepts.

4.7.1

Signal Concepts

An electronic signal may be viewed in either the time domain or the frequency domain. In the time domain, a signal’s amplitude is displayed as a function of time as shown in Fig. 4.7a left. The waveform illustrated is a sine wave with an amplitude (A) measured in volts and a frequency (f) measured in Hertz (Hz). A frequency of one Hertz is equivalent

4.7

Active Filters

187

A

A t(s)

f = 1/T

f(Hertz)

T

(a) Time domain versus frequency domain.

20

20K

Bass (60 to 250 Hz)

Midrange (500 Hz to 2 KHz)

Treble (6KHz - 20KHz)

f (Hertz)

(b) Human audible spectrum Fig. 4.7 Time and Frequency domain

to one cycle per second. A signal’s frequency is calculated by first measuring its period of repetition (T) in seconds and then inverting the result to obtain the frequency in Hz. That is, . f [H z] = 1/T [s]. The oscilloscope is used to display a signal in the time domain and also measure its period. The same signal may be observed in the frequency domain using a spectrum as shown in Fig. 4.7a right. A spectrum provides the signal’s amplitude (A) and frequency (f). As previously mentioned the time and frequency domain is linked by . f [H z] = 1/T [s]. A signal may have one frequency such as the sine wave or it may consist of multiple frequencies such as music or biomedical signals. Example: Audio spectrum. Provided in Fig. 4.7b is the human audio spectrum. Frequencies range from 20 Hz through 20 Khz. The spectrum may be divided into broad categories of Bass, Midrange, and Treble.

4.7.2

Filter Concepts

An ideal filter is characterized by a number of parameters as shown in Fig. 4.8a. The filter has a passband where signal frequencies are passed through without attenuation. It also has a stop band where signal frequencies are blocked or attenuated to zero. The two bands are separated at the cutoff frequency (. f c ) (USAFA, Webster and Nimukar).

188

4 Operational Amplifiers and Filtering

passband stopband A

f(Hertz)

fc

(a) Ideal filter characteristics. passband stopband

stopband

A

passband

A

fc

f(Hertz)

(b) Ideal low pass filter (LPF).

(c) Ideal high pass filter (HPF).

stopband passband stopband A

f(Hertz)

fc

passband stopband passband A

fc1

fc2 f(Hertz)

(d) Ideal band pass filter (BPF).

fc1

fc2 f(Hertz)

(e) Ideal band reject filter (BRF).

Fig. 4.8 Ideal filter characteristics

As shown in Fig. 4.8b there are four common filter configurations: • low pass filter: passes signal frequencies below the cutoff frequency (. f c ). • high pass filter: passes signal frequencies above the cutoff frequency (. f c ). • band pass filter: passes signal frequencies between the two cutoff frequencies (. f c1 and . f c2 ). • band reject or notch filter: rejects signal frequencies between the two cutoff frequencies (. f c1 and . f c2 ). Ideal filter characteristics are a first approximation when designing a desired filter. They also serve as a benchmark for comparison for nonideal filters. Nonideal filters have parameters used to define their performance. The signal gain is described as a transfer function (Stephenson): .

T (ω) = Vo (ω)/Vi (ω)

4.7

Active Filters

189

where: ω = 2π f

.

and f is the frequency in Hertz. The transfer function has a magnitude: |T (ω)|

.

and a phase shift expressed in degrees as: φ(ω)

.

The magnitude response is usually expressed as a filter gain in dB: .

G(ω) = 20log10 |T (ω)|

As can be seen, the filter’s phase shift and magnitude response are dependent upon the signal’s frequency components. Ideally, a filter will pass signal frequencies in its passband up to the cutoff frequency. However, nonideal filters do not have a sharp cutoff frequency. Instead, the gain of the filter begins to roll off as the cutoff frequency is approached as described by the gain and phase shift equations. The signal amplitude continues to roll off beyond the cutoff frequency as determined by filter components and filter complexity (order) as shown in Fig. 4.9a. The cutoff frequency is defined as the frequency where the passband signal gain has decreased by .−3 dB. In general, to obtain a sharper transition between the pass and stop bands requires more complex filters. Signals passing through a filter also experience a phase shift expressed in degrees. This results in a signal time delay. An example phase shift for a filter as is shown in Fig. 4.9b. For a complex signal containing multiple frequencies, such as a biomedical signal, the different time delay experienced by each constituent frequency within the signal may lead to overall signal distortion. φ (degrees)

A

0 -3dB

f c

f(Hertz)

(a) Magnitude. Fig. 4.9 Nonideal filter characteristics

-90

f(Hertz) (b) Phase.

190

4 Operational Amplifiers and Filtering

4.7.3

Filter Types

Filter design has progressed over many decades. During this time several classic filter types have emerged as shown in Fig. 4.10. These include the Bessel Filter, the Butterworth Filter, the Chebyshev Filter, and the Elliptic or Cauer Filter. Each filter type has a characteristic passband, rolloff, and phase shift described by a series of mathematical polynomials (Stephenson).

A

Bessel Butterworth Chebyshev Elliptic

f(Hertz) Bessel filter - most flat passband - poorest roll-off - monotonic stopband

Chebyshev filter - passband or stopband riplle - steeper roll-off - increased attenuation in stopband

Butterworth filter Elliptic (Cauer) filter - flat passband - ripple in passband and stopband - good roll-off - steepest roll-off - monotonic stopband - more linear phase response in passband Fig. 4.10 Filter types (Stephenson)

4.7

Active Filters

4.7.4

191

Active Analog RC Filter Design

The polynomials describing the different filter types are implemented in easy–to–use design tools. The tools are readily available from multiple op amp manufacturers. Several include: • Analog Devices, Analog Filter Wizard, www.analog.com. • Microchip, Filterlab Filter Design, www.microchip.com. • Texas Instruments, Filter Design Tool, www.TI.com The active RC filter design process is shown in Fig. 4.11. Filter configurations are typically provided in the Sallen–Key topology shown in Fig. 4.11a. The topology consists of a second–

second-order passive RC network

V i

Vo

K

(a) Sallen-Key topology. V i

R

R

Vo

+1 C

V i

C

C

C

+1 R

R

(c) highpass filter

(b) lowpass filter Filter Designer - Select - Design - Analyzer

Select

Design

Select Filter Type Passband Specs - Lowpass - Gain - Highpass - Center Frequency - Bandpass - Bandwidth - Bandstop - Ripple - Allpass

Stopband Specs - Filter Order - Bandwidth - Attenuation

Analyze Filter Response - Bessel - Butterworth - Chebyshev : :

(d) filter design process Fig. 4.11 Filter design (Stephenson, Horowitz and Hill)

Select - Magnitude - Phase - Group delay - Step Response - Circuit

Vo

192

4 Operational Amplifiers and Filtering

order passive RC network coupled with an op amp. Lowpass and highpass Sallen–Key filter configurations are shown in Fig. 4.11b and c. The process followed to design a filter consists of three steps: select, design, and analyze. In the select step you choose the type of filter desired. You then specify the passband specifications, stopband specifications, and filter response as shown in Fig. 4.11d. The filter’s characteristics are then analyzed. The filter design tools also provide a recommended filter schematic, recommended op amp(s), and resistive and capacitive component values. The automated tools are a powerful method to iteratively design and analyze a desired filter.

4.8

Instrumentation Amplifiers

The instrumentation amplifier is a classic three op amp design as shown in Fig. 4.12. Two op amps are used as inputs and the other op amp is configured as a difference amplifier. The input op amps may be configured as voltage followers or as noninverting amplifiers as shown. The instrumentation amplifier enjoys high input impedance, voltage gain, high CMRR (Faulkenberry, Sedra and Smith). Instrumentation amplifier gain is shown in Fig. 4.12. Resistors. R1 ,. R2 , and. R3 are typically fixed at manufacture and internal to the op amp. This allows the instrumentation amplifier gain to be set by a single external resistor (. RG ). Instrumentation amplifiers are available from a wide variety of manufacturers.

4.9

Isolation Amplifiers

As mentioned in the safety appendix, isolation amplifiers are used to minimize the chance of leakage currents flowing into the heart or other vital organs through conductive leads. Isolation amplifiers provide an electrical barrier between the amplifier’s input and output. The barrier may be constructed using inductive, capacitive, or optical techniques. We explore isolation amplifiers in the upcoming Application and Question sections.

4.10

Application: Single–Lead Heart Rate Monitor-AD8232

The Analog Devices AD8232 is a single–lead heart rate monitor front end. The term lead refers to a specific configuration of electrodes for electrocardiogram (ECG) heart monitoring. The AD8232 implements many of the op amp concepts discussed in this chapter. It features circuitry to measure, amplify, and condition signals from the body to provide an ECG signal (AD8232). For ECG background information, please refer to the next chapter.

4.10

Application: Single–Lead Heart Rate Monitor-AD8232

193

+

Vin1

R3

R2 R

1

-

RG R

+ 1 R2

Vin2

Vout

Gain (Av) = Vout / (Vin2 - Vin1) = (1+ (2R1/RG)) (R3/R2)

R3

+

(a) Instrumentation amplifier (Sedra and Smith). Vin1 VP = VN

+

Vout1

1. Apply ideal conditions: VP = VN, IP = IN = 0

R3

R2

I =0 N Vin1

2. Define VG and IG: VG = Vin2 - Vin1, IG = VG/RG

R I 1 G

VG

RG

+

IG R

Vin2

1

I =0 N VP = VN Vin2

R2

+

+

IG

Vout

R3

Vout2

difference amplifier

3. Define Vout2 - Vout1: Vout2 - Vout1 = (R1/RG)VG+(RG/RG)VG+(R1/RG)VG 4. Gain (Av) = Vout / (Vin2 - Vin1) = (1+ (2R1/RG)) (R3/R2)

(b) Instrumentation amplifier analysis (Sedra and Smith). Fig. 4.12 Instrumentation amplifier (Faulkenberry, Sedra and Smith)

Sparkfun (#SEN–12650) provides the AD8232 on a breakout board with convenient connections for ECG lead connection and integration with an Arduino–based microcontroller as shown in Fig. 4.13. We use the “Heart_Rate_Display.ino” sketch available at https://github.com/sparkfun/ AD8232_Heart_Rate_Monitor/blob/master/Software/Heart_Rate_Display_Arduino/ Heart_Rate_Display_Arduino.ino to capture and display the ECG signal using the Serial Plotter tool within the Arduino IDE.

194

4 Operational Amplifiers and Filtering 9 VDC battery clip

RA

LA

RL

Cable

Signal Connection

Black

RA (right arm)

Blue

LA (left arm)

Red

RL (right leg)

to pin 11 to pin 10

Fig. 4.13 Analog Devices AD8232 single–lead heart rate monitor front end. Image courtesy of SparkFun (www.sparkfun.com)

4.10

Application: Single–Lead Heart Rate Monitor-AD8232

195

/********************************************************************* Heart_Rate_Display.ino Demo Program for AD8232 Heart Rate sensor. Casey Kuhns @ SparkFun Electronics 6/27/2014 https://github.com/sparkfun/AD8232_Heart_Rate_Monitor The AD8232 Heart Rate sensor is a low cost EKG/ECG sensor. This example shows how to create an ECG with real time display. The display is using Processing. This sketch is based heavily on the Graphing Tutorial provided in the Arduino IDE. http://www.arduino.cc/en/Tutorial/Graph Resources: This program requires a Processing sketch to view the data in real time. Development environment specifics: IDE: Arduino 1.0.5 Hardware Platform: Arduino Pro 3.3V/8MHz AD8232 Heart Monitor Version: 1.0 This code is beerware. If you see me (or any other SparkFun employee) at the local pub, and you’ve found our code helpful, please buy us a round! Distributed as-is; no warranty is given. ************************************************************************/ void setup() { // initialize the serial communication: Serial.begin(9600); pinMode(10, INPUT); //Setup for leads off detection LO + pinMode(11, INPUT); //Setup for leads off detection LO } void loop() { if((digitalRead(10) == 1)||(digitalRead(11) == 1)) { Serial.println(’!’); } else { //send the value of analog input 0: Serial.println(analogRead(A0)); } //Wait for a bit to keep serial data from saturating delay(1); } /*********************************************************************

196

4 Operational Amplifiers and Filtering

We connect the AD8232 to the Arduino UNO R3 as shown in Fig. 4.13. Note that a 9 VDC battery is used to power the circuit. The ECG sensor–cable electrode pads, 3 connector, (Sparkfun #CAB–12970) are connected to the AD8232 and to the body as shown in the figure. The disposable surface electrodes–24 mm (Sparkfun #SEN–12969) are attached to the sensor cables electrode pads. The surface electrodes have a peel–and–stick reservoir containing electrode paste. Once you have successfully displayed your ECG, extend the application to include the following: • • • •

Display and capture the ECG signal using BioMedVue introduced in Chap. 1. Blink an LED at the rate of the measured heart rate.2 Display the measured heart rate in beats per minute (BPM). Equip the AD8232 heart rate monitor with optical isolation. Please see Sparkfun BOB– 09118 opto–isolator breakout.

4.11

Summary

This chapter was about the op amp. The op amp is used extensively in bio–related applications to interface transducers and provide active filtering. We began the chapter exploring op amp origins and development. We then described the ideal op amp and used it as a benchmark for real world, nonideal op amps. We then investigated how to compensate for nonideal op amp parameters. Next, we reviewed common op amp circuit configurations used extensively in instrumentation applications. We then used the circuit configurations to explore transducer interface and active filter applications. We concluded the chapter by investigating the need for instrumentation and isolation amplifiers. We closed with an application related to the electrocardiogram (ECG)–a single lead heart rate monitor.

4.12

Problems

1. What are the ideal operational amplifier characteristics? What prevents an op amp from performing in an ideal manner? 2. In your own words describe each of the op amp nonideal parameters. 3. Derive each of the output equations for the classic operational amplifier configurations. 4. In your own words describe the characteristics of each classic filter type. 5. Derive the output equation for the instrumentation amplifier. 6. Research a specific instrumentation amplifier. What are its values for R1, R2, and R3? 2 Hint: Set a software threshold to determine when the QRS complex reaches a value higher than the

rest of the ECG waveform.

References

197

7. Design an active RC filter for ECG applications. The filter should have a bandwidth up to 2 KHz and filter out 60 Hz noise. 8. In the safety appendix we discuss the need and importance of isolation amplifiers. Write a one page point paper discussing the need for isolation amplifiers and their theory of operation. Discuss inductive, capacitive, and optically–based isolation amplifiers.

References 1. Analog Devices AD8232 Single–Lead Heart Rate Monitor Front End data sheet, www.analog. com. 2. L.M. Faulkenberry, An Introduction to Operational Amplifiers, John Wiley & Sons, 1977. 3. Horowitz P, Hill W (2015) The Art of Electronics, third edition, Cambridge University Press. 4. W. Jung, Op Amp History, Analog Devices www.analog.com. 5. J.R. Ragazzini, R.H. Randall, and F.A. Russell, Analysis of Problems in Dynamics by Electronic Circuits, Proceedings of the I.R.E., 444–452, May 1947. 6. A.S. Sedra and K.C. Smith, Microelectronics, Oxford University Press, 2004. 7. F.W. Stephenson, RC Active Filter Design Handbook, John Wiley & Sons, 1985. 8. D.F. Stout and M. Kaufman, Handbook of Operational Amplifier Circuit Design, McGraw–Hill Book Company, 1976. 9. J.G. Webster and A.J. Nimunkar, Instrumentation Application and Design, fifth edition, John Wiley & Sons, 2020.

5

Biopotentials

Objectives: After reading this chapter, the reader should be able to • • • • •

Describe the origin of biopotentials at the cellular level; Explain the relationship between cellular biopotentials and biomedical signals; Describe the transducing action of the electrode; Define the difference between ionic current and electron current; Describe the origin and meaning of the electromyogram (EMG), electrocardiogram (ECG), and electroencephalogram (EEG) signals; and • Employ appropriate Arduino and support hardware to measure EMG, ECG, and EEG signals.

5.1

Overview

In this chapter we explore the fascinating topic of body electrochemistry leading to biopotentials. We begin by examining how measurable electric potentials are generated at the individual cellular level and how they result in important biological signals to monitor the health and wellbeing of the muscles, heart, and brain. For each of these signals we explore their origins, meaning, and measurement. For signal measurement we employ commercially available, Arduino–compatible support boards from several manufacturers. The manufacturers have emphasized the products are not medical devices and they are not intended to be used as such or as an accessory to such nor diagnose or treat any conditions. Furthermore, they recommend using the devices and support processors on battery power. In the examples that follow we comply with this guidance.

© The Author(s), under exclusive license to Springer Nature Switzerland AG 2024 S. F. Barrett, Arduino VI, Synthesis Lectures on Digital Circuits & Systems, https://doi.org/10.1007/978-3-031-47130-8_5

199

200

5 Biopotentials

Throughout the chapter we provide brief tutorials on the anatomy and physiology related to the signal of interest. For a more thorough treatment of these topics the interested reader is referred to some of the classic texts by Webster et al. and Ganong.

5.2

Origins of Biopotentials

The cell is enclosed within a semipermeable membrane called the cell wall. Ions surround the cell in 1the extracellular fluid (ECF) but also are within the cell’s interior cytoplasm. An ion is a charged atom due to the loss (positive) or gain (negative) of an electron. Figure 5.1 provides a closeup view of a portion of the cell wall at different stages in generating an action potential. Common cellular ions include Sodium (. N a + ), Potassium (. K + ), and Chloride (.Cl − ). The cellular wall contains channels selective for Sodium and Potassium ions. There is also Sodium–Potassium pumps bringing Potassium from outside the cell to the inside and Sodium from inside the cell to the outside. Due to the relative imbalance of ion concentrations between the inside and outside of the cell, there exists a cellular resting potential of approximately .−70 mV. The Goldman constant–field equation provides the cellular potential based on the relative concentrations of each ion on each side of the membrane. The cell maintains the resting potential due to the diffusion ion gradient, an inwardly directed field due to the ionic charge separation, the selective channels, and the Sodium–Potassium pump (Webster, Ganong). When an excitable cell is stimulated to a suitable level, cell depolarization is initiated. This triggers the opening of the Sodium channels and allows the Sodium ions (. N a + ) to rush into the cell’s interior and raise the cellular potential to approximately .+40 mV as shown in Figs. 5.1b and 5.2b. As shown in Fig. 5.2a the cellular interior potential is measured with reference to the ECF. Following depolarization the cell begins the repolarization phase. In this phase the Sodium channel closes and the Potassium channel opens allowing the cell to return to the resting potential as shown in Figs. 5.1c and 5.2b. During the hyperpolarization period the cell’s potential falls below the resting potential. Then during the refractory period the cell returns to the resting potential. In the refractory period the cell does not typically respond to an excitatory stimulus (Webster, Ganong). In the next several sections we explore how the electrical activity from a single cell contributes to measurable biopotentials at the body’s surface. We continue our investigation by examining how a single neuron propagates the action potential down its axon.

5.2

Origins of Biopotentials extracellular fluid +

201 Na+

Na+

Na

Na+

Na+

Na+

K+

Na+

Na+ Na+

Na+

K+ ch

cytoplasm K+ K+

K+

K+

Na+

Na+

Na+

Na+

Na+

Na+

K+

Na+

K+

K+

ATP ADP a) resting potential

Na+

K+

K+ K+

Na+

K+

Na+

K+

K+

K+

Na

Na+

Na+

K+ ch

cytoplasm K+ K+

Na+

Na+ ch

Na+

extracellular fluid +

Na+

Na+

Na+

Na+ ch

Na+

K+

K+

Na+

K+ Na+

K+

K+

K+

K+

K+

Na+

K+

Na+

K+

K+ b) depolarization

extracellular K+ fluid K+

K+

K+

Na+

K+

K+

K+

Na+

K+

+

K Na+ ch

K+ ch

cytoplasm K+

Na+

Na+

Na+ Na+

Na+

Na+

Fig. 5.1 Cellular potentials (Ganong)

Na+

K+

Na+

Na+

Na+ Na+

Na+

K+ c) repolarization

K+

K+ K+

Na+

202

5 Biopotentials

++ ++

++ - - ++ - + - + - + - ++ -- - - - ++ + ++

+

+ +

+

cell

_

+ +

+ + + + +

+40

action potential

-55

threshold potential

-70

resting potential

1

2

3

4

sti m d N epo ulu a+ la s r io iza ns ti re en on K pola ter + ri io za ns ti ex on it hy pe rp ol ar iz at io n

0

5 re f pe ract rio ory d

cell voltage [mV]

extracellular fluid a) action potential measurement.

b) cellular action potential. Fig. 5.2 Cellular potential waveform (Cromwell et al.)

6

time [ms]

5.3

Electrodes

5.2.1

203

Biological Neuron

Our brains are composed of many neurons. Neurons work together to help us learn, remember, link complex ideas, complete complex tasks, and so many other things. A diagram of a single biological neuron is provided in Fig. 5.3a. The neuron’s main processing unit is contained within the cell body or soma. The neuron collects information from nearby neurons via a network of input sensors called dendrites. The link from neuron to neuron is via a network of chemical transmitters and receivers. The input information is collected and processed by the soma. If a specific level of accumulated input information is reached, the neuron fires (depolarizes) and transmits an electrical signal down its axon. The axon is wrapped with a myelin sheath to aid in signal conduction as shown in Fig. 5.3a. When the electrical signal reaches the axon terminal fibers, a chemical transmitter is released to provide information to other nearby neurons (Stevens). The action potential propagates along the axon as shown in Fig. 5.3b. The axon is shown at different points of time. Initially the axon is shown at rest. When the soma provides the action potential, it propagates along the axon (from left to right in the figure). The action potential only travels in one direction. It does not propagate back towards the soma because the prior portion of the axon membrane is in the refractory period. As shown in Fig. 5.4, the signal propagation may be measured externally to the axon using two electrodes. When measuring signals at the body surface we do not measure from a single cell. Signals of interest such as the EMG, EEG, and ECG are measured with an electrode (or electrodes) with another electrode serving as a reference point. Therefore, the measured signal is a collection of individual cellular potentials. By placing the electrodes at the appropriate places and configurations on the body surface different diagnostic signals may be collected (Cromwell et al.). In the next section we investigate the transducing action of a biomedical electrode.

5.3

Electrodes

In this section we explore the measurement of biological signals of interest such as the EMG, EEG, and ECG. The signals are measured at the body’s surface using biomedical electrodes. We begin with a description of the transducing action performed by an electrode of converting ionic current within the body to electron current for signal measurement and conditioning. Although there are many types of biomedical electrodes, they all have many features and concepts in common. We limit our discussion to the disposable Ag/AgCl (Silver/Silver Chloride) surface electrode used in the book. We present an equivalent electrical circuit to discuss the two key electrode interfaces: the metal electrode/electrolyte interface within the electrode and the electrolyte/skin interface. We also discuss the electrode interface to an

204

5 Biopotentials

inputs

inputs

dendrites

inputs cell body

inputs

myelin sheath

axon

inputs

terminal fibers

outputs

myelin

myelin

+ -

+ at rest

+

+

+ -

+ -

+ -

+ -

+

+

+

+

-

+ -

+ -

+ -

+

+

+

+

-

+ -

+ -

+

+

+

+ -

+

+

-

+

-

propagation + -

outputs

+ -

+ -

+

a) Neuron (Stevens).

axon

axon

depolarization myelin

+ -

+

+ refractory

+

-

axon

depolarization myelin

+ -

+ -

+

+ refractory

depolarization

b) action potential propagation in the axon (Ganong).

Fig. 5.3 Biological neuron

axon

5.3

Electrodes

205

t0 myelin t0 myelin t1

+ -

+ -

+ -

+ -

+ -

+

+

+ at rest

+

+

+

-

+ -

+ -

+ -

+ -

+

+

+

+

+

+

-

+ -

+ -

+ -

+

+

+

+

+

-

+ -

+ -

+

+

+

+

-

+ -

+

+

-

t1 axon

axon

depolarization myelin t2

+ -

+ refractory

-

axon

depolarization myelin t3

+ -

+ -

+

+ refractory

-

axon

depolarization myelin t4

+ -

+ -

+ -

+

+

+ refractory depolarization

-

propagation biphasic axon action potential

Fig. 5.4 Biphasic axon action potential (Ganong)

axon

t2

t3

t4

206

5 Biopotentials

instrumentation amplifier discussed in the pervious chapter. Lessons learned may be applied to other electrode types.

5.3.1

Theory

Provided in Fig. 5.5a is a disposable surface electrode we use to measure biological signals of interest such as the EMG, EEG, and ECG. As shown in Fig. 5.5b the electrode top contains a metal snap to interface the electrode metallic disc to the electronic instrumentation lead (wire cable). The bottom view shows the metal disk interface to an electrolyte gel. An electrode side view 5.5c shows how the electrolyte gel provides a stable interface with the skin surface. The skin consists of several layers including the epidermis, dermis, and subcutaneous layer (Webster). Overall the electrode serves as a transducer to convert the ionic current based biological signal of interest to an electron based current for instrumentation measurement. The transduction process consists of two different key interfaces: the metal electrode/electrolyte interface within the electrode and the electrolyte/skin interface. The metal electrode/electrolyte interface is illustrated in Fig. 5.5d and e. As shown in (d) a metal electrode (e.g. Silver) is coupled with an electrolyte (e.g. Silver Chloride). The net current flow at the interface consists of several components. These include the flow of electrons opposite in direction to the net current, cations (.C + ) moving in the same direction of the net current, and also anions (. A− ) in the electrolyte moving in opposition to the net current (Webster). As shown in e) the charges cross the interface as several chemical reactions. The metal (Silver) discharges ions into the electrolyte and the ions in the electrolyte combine with them. This results in an electrode half–cell potential associated with the specific metallic/electrolyte pair chosen. The second interface is at the electrolyte/skin barrier. The skin acts a membrane between the electrolytes in the electrode and the body fluids. The membrane voltage consists of two components: the contact potential of the electrolyte/skin interface and the biological signal of interest (e.g. EMG, EEG, and the ECG). A representative equivalent circuit of the two electrode interface is provided in Fig. 5.5f. The equivalent circuit models key interfaces and components within the electrode/skin interface (Webster). To measure the biological signal of interest a signal electrode(s) is used with a reference electrode as shown in Fig. 5.5g. The signals from each electrode are provided as inputs to an instrumentation amplifier. The amplifier provides the difference between the two signals. The resulting signal is the biomedical signal of interest. As discussed in Chap. 4, an instrumentation amplifier provides high impedance inputs as well as a high CMRR (Cromwell et al., Sedra and Smith).

5.3

Electrodes

Fig. 5.5 Electrodes (Covidien, Cromwell, Ganong, Webster)

207

208

5.3.2

5 Biopotentials

Some Practical Matters

For the remainder of the chapter we explore a variety of biomedical signals. For each signal we provide background theory, fundamental anatomy and physiology, a description of signal characteristics, and a method to measure the signal using commercially available signal capture and conditioning interface cards. The signals are measured using electrodes discussed in this section. To obtain a good characteristic signal, a low impedance electrode to skin interface is essential. The interface is enhanced by cleaning the electrode site on the skin with soap and water to remove dead skin cells lotion, oil, etc. (www.biopac.com).

5.3.3

Electrocardiogram (ECG)

The electrocardiogram (ECG or EKG) is a vital diagnostic tool to measure multiple aspects of cardiac function and health. We begin with a description of the cardiac circulation and conduction system. We discuss them separately but the concepts are intricately entwined in proper cardiac operation. We then explore how to measure the ECG signal using a variety of electrode configurations called leads. We follow up with the use of MIKROE’s ECG Click to measure and display the characteristic ECG signal.

5.3.3.1 Cardiac Circulation and Conduction To better understand the origin and importance of the ECG signal we investigate the cardiac circulation and conduction. We discuss them separately but the concepts are intricately entwined in proper cardiac operation. Cardiac circulation is illustrated in Fig. 5.6. We begin at the right atrium. The right atrium receives deoxygenated blood (shown in blue) returning from the body. When the atria contract, blood is forced through the tricuspid valve (TV) into the right ventricle. When the ventricles contract, blood is forced out of the right ventricle through the pulmonary valve (PV) and to the lungs. Within the lungs the blood is oxygenated (shown in red) and returns to the left atrium. When the atria contract the blood is forced into the left ventricle via the mitral valve (MV). When the ventricles contract, the blood is forced out through the aortic valve (AV) and out to the body. The blood then returns to the right atrium. Cardiac circulation is orchestrated by the activity of the cardiac conduction system illustrated in Fig. 5.7. The sinus node contains spontaneous activated cells initiating the cardiac conduction cycle. The signal propagates radially across the atria and causes atria contraction. The signal converges and experiences a short (0.1 s) delay in the atrioventricular (AV) node. The signal is conducted via the atria–ventricular bundle (AVB) and conducted via the right and left bundle branches (RBB and LBB) through the Purkinje fibers. The signals

5.3

Electrodes

209

the lungs

right atrium

left atrium

MV

TV

right ventricle

PV

left ventricle

TV: tricuspid valve PV: pulmonary valve MV: mitral valve AV: aortic valve

AV

the body Fig. 5.6 Cardiac circulation (Cromwell)

enveloping the ventricles cause them to contract. This cycle repeats as controlled by the spontaneous, regular activation of the sinus node (Ganong, Martini).

5.3.3.2 ECG Leads and Signals The function of the cardiac conduction cycle is captured at the skin’s surface using a series of twelve different electrode configurations called leads as shown in Fig. 5.8. The leads are subdivided into three categories (Cromwell, Webster): • The bipolar limb leads include leads I, II, and III (shown in green). As the name implies, the signals from two (bi) electrodes are fed to the inputs of a differential amplifier with

210

5 Biopotentials R P: atria depolarization PR: AV node delay QRS: ventricle depolarization ST: begin ventricle repolarization T: ventricle repolarization T

P

S

Q

sinus node right atrium AVN: A-V node

left atrium

AVN

AVB MV

TV RBB: right bundle branch

RBB right ventricle

Purkinje fibers

Fig. 5.7 Cardiac conduction (Cromwell)

AVB: A-V bundle

LBB: left bundle branch

LBB left ventricle

Purkinje fibers

5.3

Electrodes

Right Arm (RA) -

211 Lead I

-

+

Left Arm (LA) -

aVL aVR V1

V2 V3 V4

Lead II

V6 V5

Lead III

aVF

+

+ Left Leg (LL)

Fig. 5.8 ECG leads (Cromwell, Webster)

reference to the right leg electrode signal serving as the ground reference. Each specific lead uses a different bipolar electrode pair for measurement. The plus and minus signs indicate the differential amplifier input for each electrode. The leads include: – Lead I: right arm (–), left arm (+), right leg (reference) – Lead II: right arm (–), left leg (+), right leg (reference) – Lead III: left arm (–), left leg (+), right leg (reference) • The unipolar or augmented limb leads designated aVR, aVL, and aVF (shown in red) sum the currents from two limb electrodes relative to a third lead. The ‘aV’ indicates an augmented voltage; whereas, the ‘R’ designates the right arm, the ‘L’ is the left arm, and the ‘F’ designates the foot (left leg). The right leg (RL) serves as the ground reference. These are considered unipolar leads since the designated electrode serves as the positive electrode while the other two electrodes are combined to serve as the negative amplifier input. • The unipolar chest leads or ‘V’ leads (shown in blue) consists of a series of six electrode positions across the chest.

212

5 Biopotentials

A particular lead is chosen to monitor the electrical cardiac conduction cycle of the heart. As seen in Fig. 5.7, each portion of the ECG characteristic signal corresponds to a particular event in the cardiac conduction cycle.

5.3.3.3 Application: Measuring the ECG Signal To measure the ECG signal we use the Mikroe ECG Click.1 The ECG Click is equipped with a seven stage circuit to provide protection, amplification (2), filtering (3), and a driven right leg (DRL) circuit. The ECG Click Bundle includes the Click, electrode cabling, and disposable electrode pads (www.mikroe.com). The ECG Click is mounted to an Arduino UNO Click Shield as shown in Fig. 5.9. The color coded electrodes are connected as shown in Fig. 5.9. The following sketch from Electronza captures the ECG signal on the Arduino UNO R3 analog input A0 and displays it on the Arduino IDE Serial Monitor or Plotter (www.electronza.com). The support computer and the Arduino UNO should be on battery power during the measurement. //**************************************************************** //ECG click: plotting data using Serial plotter from Arduino IDE // //Notes: // - Ensure serial monitor set to 57600 Baud // //Source: www.electronza.com //**************************************************************** void setup() { Serial.begin(57600); } void loop() { int sensorValue = analogRead(A0); Serial.println(sensorValue); delayMicroseconds(3900); }

//initialize serial comm

//read analog pin 0 //print out the value read //about 256Hz sample rate

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

1 The manufacturers have emphasized these products are not medical devices and they are not

intended to be used as such or as an accessory to such nor diagnose or treat any conditions. Furthermore, they recommend using the devices and support processors on battery power.

5.3

Electrodes

213

a) ECG Click with Arduino UNO click Shield.

RA

LA

LL

c) ECG electrode lead set.

Cable

Signal Connection

White

RA (right arm)

Black

LA (left arm)

Red

LL (left leg)

b) ECG electrode lead configuration. Fig. 5.9 ECG click (www.mikroe.com[SB1]). Image courtesy of SparkFun (www.sparkfun. com)

214

5.3.4

5 Biopotentials

Electroencephalogram (EEG)

The brain is an amazing organ that integrates, interprets, and coordinates most bodily functions. The brain along with the spinal cord comprise the central nervous system (CNS). The CNS collects information from throughout the body through a series of anatomic sensors and relays it to the brain for higher level processing. The brain processes the information and provides responses in the result of control signals that go back out through the CNS to control and regulate the body. There is a strong parallel between the brain and the function of a microcontroller. A microcontroller employs a wide variety of sensors to collect information to accomplish a given task. The data collected from the sensors are interpreted and decision actions made via a software based algorithm stored with the microcontroller’s memory. In response to decisions made by the algorithm, the microcontroller issues signals to control and regulate a process. In this section we provide a brief overview of the brain, the origin and measurement of electroencephalogram (EEG) signals, and then use an EEG Click to measure a single channel of an EEG signal.

5.3.4.1 Brain Structure The basic structure of the human brain is provided in Fig. 5.10. The brain is subdivided into lobes including the frontal lobe, the parietal lobe, temporal lobe, and the occipital lobe. Sensory information from different parts of the body are routed to the different specialized portions of the brain for processing as shown. Different portions of the brain are responsible for specialized higher order tasks such a planning and consciousness, speech, hearing, and vision. The specialized processing is accomplished by massive networks of interconnected neurons previously discussed. Within a given neuron activity is electrical; while, communication between neurons is a chemical across synapses.

5.3.4.2 EEG The electrical activity of the neural networks may be monitored using different types of electrodes. We concentrate on electrodes connected external to the brain on the scalp surface. The signal collected is called the electroencephalogram (EEG). The signal collected is not from a single neuron but from multiple neurons within the area of the measuring electrode. The EEG signal is the sum of the neuron signals within the electrode area each with their own contribution, function, and orientation relative to the electrode. As an example, a choir consists of many independent voices with different features such as tone, timbre, placement, and vibrato. Based on these features voices may be placed in four common categories of soprano, alto, tenor, and baritone. A recording of the choir collects the sum of the voices each with their own contribution, function, and orientation relative to

5.3

Electrodes

215

Fig. 5.10 Brain structure

the microphone. This is similar to the collective signal from multiple neurons measured by an EEG electrode. For EEG signal collection a standard pattern of surface electrodes is used as shown in Fig. 5.11a. The EEG electrode placement has been standardized for some time. Placement is based on four fundamental premises: (1) electrode placement is correlated to specific skull landmarks, (2) full coverage of the brain surface, (3) electrode placement designation is correlated to brain area covered, and (4) data collection correlated to the area measured. The abbreviations used for electrode placement include frontal polar (Fp), frontal (F), central (C), parietal (P), and occipital (O). These correspond to the lobes previously discussed (Klem). Characteristic EEG signals are shown Fig. 5.11b. They are characterized by signal frequency and brain activity. The Alpha waves correspond to a brain that is awake and at rest. The Beta wave corresponds to a brain that is a awake with mental activity. The Theta wave corresponds to a sleeping brain and the Delta wave for a brain in deep sleep (Ganong, Webster).

216

5 Biopotentials

Fp1

F7

F3

G

FZ

Fp2

Alpha 8-13 Hz

F8

F4

Beta 14-30 Hz A1

T3

C3

CZ

P3

PZ

C4

T4

A2 Theta 4-7 Hz

P4

T5

T6 O1

Delta < 3.5 Hz

O2

a) EEG electrode placement (Klem).

c) MIKROE EEG Click (MIKROE).

b) Characteristic EEG signals (Webster).

d) EEG Click electrode placement.

Fig. 5.11 Electroencephalogram (EEG)

To measure the EEG we use the MIKROE EEG Click shown in Fig. 5.11c.2 The EEG Click is equipped with a Burr Brown INA114 precision instrumentation amplifier (Burr–Brown). It is also equipped with the MCP609 quad op amp. The MCP609 is used for additional signal amplification and filtering. The specifications of the filter is not available. 2 The EEG Click is not suitable for clinical examination but is useful for providing insight into brain

activity (SparkFun.com).

5.3

Electrodes

217

The EEG Click measures a single EEG channel using a three electrode configuration. Two electrodes are placed behind the ears and the third electrode is placed on the forehead as shown in Fig. 5.11d. If the three electrode cable is used from the ECG Click, the electrode designated “LA” equipped with a silver/silver chloride disposable electrode should be placed on the forehead. The other two electrodes (RA and LL) equipped with silver/silver chloride disposable electrodes should be placed behind the each ear. To faithfully sample the EEG signal, it must be captured by the Arduino ADC system to satisfy the Nyquist criterion discussed in Chap. 2. The Nyquist criterion requires a signal to be sampled at a frequency at least twice as high as the anticipated frequency. The signal parameters shown in Fig. 5.11b Beta wave has a frequency content up to 30 Hz. Webster indicates the frequency content of the EEG may go as high as 150 Hz (Webster). If the signal is sampled at 300 Hz, we need to complete a ADC conversion of the EEG signal at 3.33 ms or 3,333 microsecond intervals. This sampling requirements is well within the capability of the Arduino UNO R3 equipped with the Microchip ATmega328. The following sketch captures the EEG signal on Arduino pin A0 every 3,333 microseconds. We again use the Arduino UNO Click Shield to provide the interface between to MIKROE EEG Click and the Arduino UNO R3. The sampled EEG signal may be displayed using the serial plotter within the Arduino IDE. The support computer and the Arduino UNO should be on battery power during the measurement. Using techniques discussed in Chap. 4, additional signal filtering may be accomplished. //**************************************************************** //EEG click: plotting data using Serial plotter from Arduino IDE ///**************************************************************** void setup() { //initialize serial communication at 57600 bits per second: Serial.begin(57600); } void loop() { int sensorValue = analogRead(A0); Serial.println(sensorValue); delayMicroseconds(3333); }

//read the input on analog pin 0 //print out the value read //about 300 Hz sample rate

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

218

5.3.5

5 Biopotentials

Electromyogram the EMG

In this section we explore the electromyogram or EMG. We begin with a brief review of muscle type and then concentrate on skeletal muscles and their features. We then investigate the origin of the EMG signal and its measurement using a MyoWare 2.0 muscle sensor.

5.3.5.1 Muscle Throughout the body there are three main types of muscle including cardiac, smooth, and skeletal muscles. As seen earlier in the chapter, cardiac muscle surrounds the atria and ventricles and are essential for the proper operation of the circulatory system. Smooth muscle is found throughout the body and aids organs in their proper function. Skeletal muscles are also found throughout the body and are essential for movement, posture, position, support, and assist in maintaining body temperature (Martini). As shown in Fig. 5.12, skeletal muscle consists of a number of individual muscle fibers. The muscle fibers are controlled by motor neurons coming from the spinal cord. The motor neurons typically receive stimulus from the muscular control centers of the brain. The brain with the spinal cord are referred to as the central nervous system or CNS. The spinal cord serves to transmit signals to and from the brain (Martini). When suitably stimulated by a nerve impulse, the muscle goes through a characteristic all–or–nothing twitch response cycle as shown in Fig. 5.13. After a brief latency period the muscle goes through a contraction phase where it reaches its maximum tension followed by a relaxation phase. If the muscle receives multiple stimuli, a new cycle is initiated before the current one completes. This results in summation and increased muscle tension. If the stimuli frequency increases further, there is an absence of the relaxation phases and the muscle experiences total tetanus at maximum tension (Martini). Muscle strength is also affected by the number of individual muscle fibers stimulated in a specific activity. As shown in Fig. 5.12, a single motor neuron may activate multiple muscle fibers. The motor neuron with its associated muscle fibers is called a motor unit. Multiple motor units may be stimulated for a given muscle activity. The more motor units activated result in a stronger muscle contraction.

5.3.5.2 EMG Origins and Measurement Fig. 5.14a shows the EMG signal measured on the body’s surface. The EMG is the summation of the electrical signals from multiple individual motor units. We use the MyoWare 2.0 muscle sensor shown in (b) to capture the EMG signal. The sensor processes the EMG signal through a differential amplifier and band pass filter to provide the raw EMG signal. The signal is further processed to yield the rectified signal and then passed through a low pass filter to obtain the envelope signal shown in (c). Each of these signal steps are available for analysis from the MyoWare 2.0 Muscle Sensor.

5.3

Electrodes

Fig. 5.12 Skeletal muscle (Webster)

219

220

5 Biopotentials

tension

maximum tension

resting phase

contraction phase

relaxation phase

latent period

time (msec) stimulus

a) Tension development.

maximum tension

tension

tension

maximum tension

stimulus

stimulus b) Repeated stimulation.

Fig. 5.13 Skeletal muscle tension (Martini)

c) Complete tetanus.

5.3

Electrodes

221

Fig. 5.14 The EMG (Webster). Image courtesy of SparkFun (www.sparkfun.com)

The MyoWare 2.0 Muscle Sensor is equipped with three electrode tabs designated mid, end and reference (ref). The ‘mid’ electrode is connected to the muscle group middle. The ‘end’ electrode is connected to the muscle group end. The ‘ref’ electrode to a separate part of the body. The Disposable electrodes may be directly attached to the electrode tabs and applied to different muscles as shown in Fig. 5.15(MyoWare).

222

5 Biopotentials

bicep forearm

calf

Fig. 5.15 EMG electrode placement with the MyoWare 2.0 muscle sensor (MyoWare). Image courtesy of SparkFun (www.sparkfun.com)

For basic measurements, the MyoWare 2.0 Muscle Sensor is connected to the Arduino UNO R3 using the connection points shown in Fig. 5.14b bottom view. The ‘VIN’ point is connected to 5 VDC on the Arduino and ‘GND’ to ground. The EMG signal (RAW, RECT, or ENV) is provided to analog input A0. The signal may be captured and displayed with the following sketch using the Serial Plotter within the Arduino IDE. //************************************************************* //MyoWare Example_01_analogRead_SINGLE //SparkFun Electronics //Pete Lewis //3/24/2022 // //License: This code is public domain but you buy me a beverage

5.3

Electrodes

223

//if you use this and we meet someday. // //This code was adapted from the MyoWare analogReadValue.ino //example found here: // https://github.com/AdvancerTechnologies/MyoWare_MuscleSensor // //This example streams the data from a single MyoWare sensor //attached to ADC A0. Graphical representation is available //using Serial Plotter (Tools > Serial Plotter menu). // //Only run on a laptop using its battery. Do not plug in laptop //charger/dock/monitor. //Do not touch your laptop trackpad or keyboard while the MyoWare //sensor is powered. // // //This example code is in the public domain. //************************************************************ void setup() { Serial.begin(115200); while (!Serial); //wait for terminal to open Serial.println(‘‘MyoWare Example_01_analogRead_SINGLE’’); } void loop() { int sensorValue = analogRead(A0); //read analog pin A0 Serial.println(sensorValue); //print out the value delay(50); //avoids overloading terminal } //************************************************************

For additional flexibility in recording, the MyoWare 2.0 Muscle Sensor may be equipped with additional hardware for distributed electrode placement and measuring several muscle groups simultaneously as shown in Fig. 5.16. In the configuration shown the Arduino UNO R3 is equipped with the MyoWare 2.0 Arduino Shield (SparkFun DEV–18426) which provides for the capture of six channels of EMG data. A specific channel is connected to a MyoWare 2.0 Muscle Sensor (SparkFun DEV–21265). The Muscle Sensor is equipped as a three–layer wafer with a Link Shield (SparkFun DEV–18425) and a Cable Shield (DEV–18336). The Sensor Cable (SparkFun CAB–12970) is equipped three Disposable Surface Electrodes (SparkFun SEN–12969). The lead electrodes are connected as follows (SparkFun):

224

5 Biopotentials

Fig. 5.16 EMG electrode placement with the MyoWare 2.0 muscle sensor and a sensor cable (MyoWare)

• the red lead is connected to the muscle group middle, • the blue lead to the muscle group end, and • the black lead is connected to another body part to serve as the reference. The MyoWare 2.0 Link Shield is equipped with an ON/OFF switch and a switch to select the EMG signal (Raw, Rectified, or Envelope) for display.

5.4

Application: Biomedical Signals with TFT Display

In the Chap. 1 application section we investigated the use of an SD card to provide a “hard drive” for data logging and storage for the ATmega2560 microcontroller. We then explored using a TFT style graphic display for illustrating data. Both the SD card and the TFT display were interfaced to the ATmega2560 via the Serial Peripheral Interface (SPI). We

References

225

then developed the “BioMedVue” data logger and display application. In this section we equip BioMedVue for logging and displaying pulse sensor data. For this application adapt the BioMedVue sketch to display the ECG, EEG, and EMG signals.

5.5

Summary

In this chapter we explored the fascinating topic of body electrochemistry leading to biopotentials. We began by examining how measurable electric potentials are generated at the individual cellular level and how they result in important biological signals to monitor the health and wellbeing of the muscles, heart, and brain. We also measured the Galvanic Skin Response (the GSR) and the oxygen content of the blood via pulse oximetry.

5.6

Problems

1. 2. 3. 4. 5.

Describe the origin of biopotentials at the cellular level. Explain the relationship between cellular biopotentials and biomedical signals. Describe the transducing action of the electrode. Define the difference between ionic current and electron current. Describe the origin and meaning of the electromyogram (EMG), electrocardiogram (ECG), and electroencephalogram (EEG) signals. 6. Explore and report on other biomedical signals such as the ENG, ERG, or EOG. 7. Why are instrumentation amplifiers used in biomedical signal measurements?

References 1. BIOPAC Systems, Inc., www.biopac.com. 2. Burr–Brown, INA114 Precision Instrumentation Amplifier, PDS–1142D Burr–Brown Corporation, 1992. 3. L. Cromwell, F.J. Weibell, E.A. Pfeiffer, L.B. Usselman, Biomedical Instrumentation and Measurements, Prentice Hall, 1973. 4. W.F. Ganong, Review of Medical Physiology, Appleton and Lange, 1989. 5. Covidien Kendall ™ ECG Electrodes Product Data Sheet, Covidien AG, 2008. 6. G.H. Klem, H.O. Luders, H.H. Jasper, and C. Elger, The ten–twenty electrode system of the International Federation, Recommendation for the Practice of Clinical Neurophysiology: Guidelines of the International Federation of Clinical Physiology (EEG Supplement 52), 1999. 7. F.H. Martini and E.F. Bartholomew, Essentials of Anatomy and Physiology, second edition, Prentice Hall, 2000.

226

5 Biopotentials

8. 9. 10. 11.

MyoWare A.S. Sedra and K.C. Smith, Microelectronics, Oxford University Press, 2004. C.F. Stevens, The Neuron, Scientific American, pp. 55–65, 1979. J.G. Webster and A.J. Nimunkar, Medical Instrumentation Application and Design, 5th edition, Wiley, 2020.

Part III Design of Medical Instrumentation

6

Embedded Systems Design

Objectives: After reading this chapter, the reader should be able to do the following: . . . . .

Define an embedded system; List all aspects related to the design of an embedded system; Provide a step–by–step approach to embedded system design; Discuss design tools and practices related to embedded systems design; and Apply embedded system design practices in the design of a microcontroller system employing several interacting subsystems.

6.1

Overview

In this chapter,1 We begin with a definition of just what is an embedded system. We then explore the process of how to successfully (and with low stress) develop an embedded system prototype that meets established requirements. We conclude the chapter with several examples.

1 The information on embedded system design first appeared in “Microcontroller Fundamentals for

Engineers and Scientists,” Morgan and Claypool Publishers, 2006. It has been adapted with permission for the Microchip ATmega328 and the Arduino–based platforms. © The Author(s), under exclusive license to Springer Nature Switzerland AG 2024 S. F. Barrett, Arduino VI, Synthesis Lectures on Digital Circuits & Systems, https://doi.org/10.1007/978-3-031-47130-8_6

229

230

6.2

6 Embedded Systems Design

What is an Embedded System?

An embedded system contains a microcontroller to accomplish its job of processing system inputs and generating system outputs. The link between system inputs and outputs is provided by a coded algorithm stored within the processor’s resident memory. What makes embedded systems design so interesting and challenging is the design must also take into account the proper electrical interface for the input and output devices, limited on–chip resources, human interface concepts, the operating environment of the system, cost analysis, related standards, manufacturing aspects, and safety (Anderson). Through careful application of this material you will be able to design and prototype embedded systems based on the Arduino microcontroller.

6.3

Embedded System Design Process

In this section, we provide a step–by–step approach to develop the first prototype of an embedded system that will meet established requirements. There are many formal design processes that we could study. We concentrate on the steps that are common to most. We purposefully avoid formal terminology of a specific approach and instead concentrate on the activities that are accomplished as a system prototype is developed. The design process we describe is illustrated in Fig. 6.1 using a Unified Modeling Language (UML) activity diagram. We discuss the UML activity diagrams later in the chapter.

6.3.1

Project Description

The goal of the project description step is to determine what the system is ultimately supposed to do. To achieve this step you must thoroughly investigate what the system is supposed to do. Questions to raise and answer during this step include but are not limited to the following: . What is the system supposed to do? . Where will it be operating and under what conditions? . Are there any restrictions placed on the system design? To answer these questions, the designer interacts with the client to ensure clear agreement on what is to be done. If you are completing this project for yourself, you must still carefully and thoughtfully complete this step. The establishment of clear, definable system requirements may require considerable interaction between the designer and the client. It is essential that both parties agree on system requirements before proceeding further in the design process. The final result of this step is a detailed listing of system requirements and related specifications.

6.3

Embedded System Design Process

231

Fig. 6.1 Embedded system design process Project Description - What is the system supposed to do? - Operating conditions and environment - Formal requirements

Background Research - Thoroughly understand desired requirements and features - Determine applicable codes, guidelines, and protocols - Determine interface requirements

Pre-Design - Brainstorm possible solutions - Thoroughly investigate alternatives - Choose best possible solution - Identify specific target microcontroller - Choose a design approach

Employ Design Tools - Structure chart - UML activity diagram - Circuit diagram - Supplemental information

Implement Prototype - Top down versus bottom up - Develop low risk hardware test platform - Software implementation

Preliminary Testing - Develop test plan to insure requirements have been met - Test under anticipated conditions - Test under abusive conditions - Redo testing if errors found - Test in low cost, low risk environment - Full up test

yes

System design need correction? no Complete and Accurate Documentation - System description - Requirements - Structure chart - UML activity diagram - Circuit diagram - Well-documented code - Test plan

Deliver Prototype

232

6.3.2

6 Embedded Systems Design

Background Research

Once a detailed list of requirements has been established, the next step is to perform background research related to the design. In this step, the designer will ensure they understand all requirements and features required by the project. This will again involve interaction between the designer and the client. The designer will also investigate applicable codes, guidelines, protocols, and safety standards related to the project. This is also a good time to start thinking about the interface between different portions of the project particularly the input and output devices peripherally connected to the microcontroller. The ultimate objective of this step is to have a thorough understanding of the project requirements, related project aspects, and any interface challenges within the project.

6.3.3

Pre–design

The goal of the pre–design step is to convert a thorough understanding of the project into possible design alternatives. Brainstorming is an effective tool in this step. Here, a list of alternatives is developed. Since an embedded system typically involves both hardware and/or software, the designer can investigate whether requirements could be met with a hardware only solution or some combination of hardware and software. Generally, speaking a hardware only solution executes faster; however, the design is fixed once fielded. On the other hand, a software implementation provides flexibility and a typically slower execution speed. Most embedded design solutions will use a combination of both hardware and software to capitalize on the inherent advantages of each. Once a design alternative has been selected, the general partition between hardware and software can be determined. It is also an appropriate time to select a specific hardware device to implement the prototype design. If a microcontroller technology has been chosen, it is now time to select a specific controller. This is accomplished by answering the following questions: . What microcontroller systems or features i.e., ADC, PWM, timer, etc.) are required by the design? . How many input and output pins are required by the design? . What is the maximum anticipated operating speed of the microcontroller expected to be?

6.3.4

Design

With a clear view of system requirements and features, a general partition determined between hardware and software, and a specific microcontroller chosen, it is now time to

6.3

Embedded System Design Process

233

tackle the actual design. It is important to follow a systematic and disciplined approach to design. This will allow for low stress development of a documented design solution that meets requirements. In the design step, several tools are employed to ease the design process. They include the following: . Employing a top–down design, bottom up implementation approach, . Using a structure chart to assist in partitioning the system, . Using a Unified Modeling Language (UML) activity diagram to work out program flow, and . Developing a detailed circuit diagram of the entire system. Let’s take a closer look at each of these. The information provided here is an abbreviated version of the one provided in “Microcontrollers Fundamentals for Engineers and Scientists.” The interested reader is referred there for additional details and an in —depth example (Barrett and Pack). Top down design, bottom up implementation. An effective tool to start partitioning the design is based on the techniques of top–down design, bottom–up implementation. In this approach, you start with the overall system and begin to partition it into subsystems. At this point of the design, you are not concerned with how the design will be accomplished but how the different pieces of the project will fit together. A handy tool to use at this design stage is the structure chart. The structure chart shows the hierarchy of how system hardware and software components will interact and interface with one another. You should continue partitioning system activity until each subsystem in the structure chart has a single definable function. UML Activity Diagram. Once the system has been partitioned into pieces, the next step in the design process is to start working out the details of the operation of each subsystem we previously identified. Rather than beginning to code each subsystem as a function, we will work out the information and control flow of each subsystem using another design tool: the Unified Modeling Language (UML) activity diagram. The activity diagram is simply a UML compliant flow chart. UML is a standardized method of documenting systems. The activity diagram is one of the many tools available from UML to document system design and operation. The basic symbols used in a UML activity diagram for a microcontroller based system are provided in Fig. 6.2 (Fowler). To develop the UML activity diagram for the system, we can use a top–down, bottom–up, or a hybrid approach. In the top–down approach, we begin by modeling the overall flow of the algorithm from a high level. If we choose to use the bottom–up approach, we would begin at the bottom of the structure chart and choose a subsystem for flow modeling. The specific course of action chosen depends on project specifics. Often, a combination of both techniques, a hybrid approach, is used. You should work out all algorithm details at the UML activity diagram level prior to coding any software. If you cannot explain system operation

234

6 Embedded Systems Design

Starting Activity

Branch

Transfer of Control

Final State

Action State

Fig. 6.2 UML activity diagram symbols. Adapted from (Barrett and Pack)

at this higher level, first, you have no business being down in the detail of developing the code. Therefore, the UML activity diagram should be of sufficient detail so you can code the algorithm directly from it (Dale). In the design step, a detailed circuit diagram of the entire system is developed. It will serve as a roadmap to implement the system. It is also a good idea at this point to investigate available design information relative to the project. This would include hardware design examples, software code examples, and application notes available from manufacturers. At the completion of this step, the prototype design is ready for implementation and testing.

6.3.5

Implement Prototype

To successfully implement a prototype, an incremental approach should be followed. Again, the top–down design, bottom–up implementation provides a solid guide for system implementation. In an embedded system design involving both hardware and software, the hardware system including the microcontroller should be assembled first. This provides the software the required signals to interact with. As the hardware prototype is assembled on a prototype board, each component is tested for proper operation as it is brought online. This allows the designer to pinpoint malfunctions as they occur.

6.3

Embedded System Design Process

235

Once the hardware prototype is assembled, coding may commence. As before, software should be incrementally brought online. You may use a top down, bottom up, or hybrid approach depending on the nature of the software. The important point is to bring the software online incrementally such that issues can be identified and corrected early on. It is highly recommended that low cost stand–in components be used when testing the software with the hardware components. For example, push buttons, potentiometers, and LEDs may be used as low cost stand–in component simulators for expensive input instrumentation devices and expensive output devices such as motors. This allows you to insure the software is properly operating before using it to control the actual components.

6.3.6

Preliminary Testing

To test the system, a detailed test plan must be developed. Tests should be developed to verify that the system meets all of its requirements and also intended system performance in an operational environment. The test plan should also include scenarios in which the system is used in an unintended manner. As before a top–down, bottom–up, or hybrid approach can be used to test the system. Once the test plan is completed, actual testing may commence. The results of each test should be carefully documented. As you go through the test plan, you will probably uncover a number of run time errors in your algorithm. After you correct a run time error, the entire test plan must be performed again. This ensures that the new fix does not have an unintended effect on another part of the system. Also, as you process through the test plan, you will probably think of other tests that were not included in the original test document. These tests should be added to the test plan. As you go through testing, realize your final system is only as good as the test plan that supports it! Once testing is complete, you might try another level of testing where you intentionally try to “jam up” the system. In another words, try to get your system to fail by trying combinations of inputs that were not part of the original design. A robust system should continue to operate correctly in this type of an abusive environment. It is imperative that you design robustness into your system. When testing on a low cost simulator is complete, the entire test plan should be performed again with the actual system hardware. Once this is completed you should have a system that meets its requirements!

6.3.7

Complete and Accurate Documentation

With testing complete, the system design should be thoroughly documented. Much of the documentation will have already been accomplished during system development. Documentation will include the system description, system requirements, the structure chart, the UML activity diagrams documenting program flow, the test plan, results of the test

236

6 Embedded Systems Design

plan, system schematics, and properly documented code. To properly document code, you should carefully comment all functions describing their operation, inputs, and outputs. Also, comments should be included within the body of the function describing key portions of the code. Enough detail should be provided such that code operation is obvious. It is also extremely helpful to provide variables and functions within your code names that describe their intended use. You might think that a comprehensive system documentation is not worth the time or effort to complete it. Complete documentation pays rich dividends when it is time to modify, repair, or update an existing system. Also, well–documented code may be often reused in other projects: a method for efficient and timely development of new systems. For the remainder of the chapter, we employ these design techniques in several examples.

6.4

Application: Visual Feedback Array

To illustrate the design process we provide an in depth, extended example. The Kinesiology and Health (KNH) Department required assistance in developing a piece of laboratory research equipment. Over the course of more than 10 years, the equipment went through three different design iterations: (1) a baseline design requiring an external signal generator, (2) a revised design incorporating the features of the signal generator and improved functionality, and (3) and a portable Arduino–based design. We begin with a project overview and then explore each design iteration (Barrett and Bundle).

6.4.1

Background

In a variety of biomechanical and physiological studies (Sundberg and Bundle, Burd et al., Fulco et al.), along with clinical rehabilitation settings (Giggins et al.), the ability to provide research participants and patients with precise and reproducible feedback on their limb displacements and velocities is important. Despite this relatively widespread recognition, options for clinicians and scientists to provide real–time, continuous kinematic feedback are limited and often expensive. For this purpose, a custom instrumentation array was developed to provide visual feedback on the desired movement cadence in conjunction with the actual limb displacements and velocities (Barrett and Bundle, Sundberg and Bundle).2 The array consists of two columns, each with 14 red high–visibility (10 mm diameter) light emitting diodes (LEDs). One array column provides the desired or imposed cadence of position change while the complementary array provides an indication of the actual rate of displacement achieved by the research participant or patient as shown in Fig. 6.3.

2 Portions of this section are adapted with permission from Barrett 2010 and Barrett and Sundberg

2017.

6.4

Application: Visual Feedback Array

237

Fig. 6.3 Visual feedback array (Barrett and Sundberg)

6.4.2

Design Iteration I: Baseline Instrument

To begin the design process, members of the research team met with the design engineer to describe the system and determine specific requirements. Problem description and background research. The basic system concept is illustrated in Fig. 6.4. The KNH researchers needed a display panel containing two columns of large (10 mm diameter) red LEDs. The LEDs needed to be viewable at a distance of approximately 5 meters. The right column of LEDs would indicate the desired level of exertion for the subject under test. This LED array is driven by an external signal generator using a low frequency ramp signal. The left column of LEDs would indicate actual subject exertion level. This array is driven by a powered string potentiometer. As its name implies, a string potentiometer is equipped with a string pull. The resistance provided by the potentiometer is linearly related to the string displacement. Once powered, the string pot provides an output voltage proportional to the string pull length. The end of the string is connected to a displacing arm on a piece of exercise equipment (e.g. a leg lift apparatus). From a safety point of view, there were no direct connection to the client. Furthermore, all equipment was powered from properly grounded commercial off–the–shelf (COTS) power supplies. After the requirements were determined, the characteristics of the available signal generator and the string pot were reviewed in detail. Pre–design. With requirements clearly understood the next step was to brainstorm possible solutions. Two possible alternatives clearly became evident: a complete hardware implementation or a microcontroller–based solution. Whichever approach was chosen, it was clear that the following features were required:

238

6 Embedded Systems Design

desired exertion

actual exertion

signal generator

5 VDC

string movement

string potentiometer

Fig. 6.4 KNH project overview. A display panel contains two arrays of 14 large (10 mm diameter) red LEDs each. The right array driven by a signal generator indicates the desired assertion level. The left array is driven by a string potentiometer transducer. This LED array indicates the actual exertion level as determined by the string length of the potentiometer (Barrett and Bundle)

. The ability to independently drive a total of 28 large (10 mm diameter) LEDs; . An interface circuit to drive each LED; . Two analog–to–digital channels to convert the respective string potentiometer and signal generator inputs into digital signals; . Input buffering circuitry to isolate and protect the panel from the string pot and signal generator and to guard against accidental setting overload; and . An algorithm to link the analog input signals to the appropriate LED activation signals. In the baseline design, a complete hardware implementation was chosen for the project. Due to the high number of output pins required to drive the LEDs and the minimal algorithm required to link the analog input to the LED outputs, it was determined that a microcontroller was not the best choice for this project.

6.4

Application: Visual Feedback Array

239

ADC

Determines LEDs to illuminate Illuminate appropriate LEDs

KNH Array Panel

Right Panel Desired Exertion

Left Panel Actual Exertion

LED interface

ADC

buffer amplifier

string pot

LED interface

ADC

buffer amplifier

signal input protection generator

Fig. 6.5 UML activity diagram and structure chart for KNH arrays (Barrett and Bundle)

Design. With a design alternative chosen, the next step was to develop a detailed design. The overall project was partitioned using the structure chart illustrated in Fig. 6.5. From the structure chart a circuit diagram was developed for each subsystem within the circuit. To develop the analog–to–digital converter with a 14–bit output a small test circuit using only four bits was first developed to test the concept. The small scale test circuit is shown in Fig. 6.6. It is basically a four bit flash ADC converter. The incoming analog voltage is simultaneously applied to a bank of analog comparators. Each comparator has a different threshold voltage. The circuit provides a rain gage display of the analog voltage. The higher the analog input voltage, the more LEDs are illuminated. The full up, two array, 14–bit output driving a total of 28 large LEDs circuit diagram is provided in Fig. 6.7. Implement Prototype and Testing. The circuit was then implemented on a powered, prototype board to ensure correct operation. The circuit was slowly brought online a subsystem at a time starting from the lowest level of the structure chart. Each subsystem was implemented and tested as it was brought online. Once the array was completely prototyped and tested, the design was converted to a printed circuit board (PCB) layout. The PCB was assembled and tested to ensure proper operation. Also, the PCB circuit was tested against the prototyped circuit.

240

6 Embedded Systems Design

threshold detectors

+5 VDC

10K

(4)

4/5 supply

+5 VDC

(2) (1) (3)

10K

(11)

220

small LED 3/5 supply

(6)

(7)

(5) 220

10K

small LED 2/5 supply

(9) (8) (10)

10K

220

small LED 1/5 supply

(13) (14) (12)

10K

220

small LED +5 VDC

voltage level for comparison Fig. 6.6 Small scale test circuit for the KNH arrays. The input voltage is compared against a bank of threshold detectors each set to a different fraction of the supply voltage. As the input voltage is increased more LEDs will illuminate. This is commonly referred to as a rain gage indicator (Barrett and Bundle)

With the circuit correctly operating, it was installed in an aluminum chassis and delivered to the Kinesiology and Health Department. The circuit was powered by a COTS power supply properly grounded to the metal display case. The research team then tested the array panel under actual laboratory conditions. As a result of the testing, several circuit modifications were required to allow a “programmable” rest and exercise period for the desired exertion array. As shown in Fig. 6.8, any rest period and exercise period may be selected by careful choice of the signal parameters applied to the desired exertion array. In the example shown, a rest period of 2s and an exercise period of 1s was desired. The signal generator was set for a ramp signal with the parameters shown. The input protection circuitry limits the excursion of the input signal to approximately 0 to 4 V.

Application: Visual Feedback Array

5K

5 VDC

5 VDC

string le ngth compe nsa tion

1100

1100

(1)

LM324

220

9 VDC

5 VDC

(16)

(4) (2)

(15)

(3)

220

(1) (1)4.7K(16)

(6)

(3)

(5)

220 (14)

(9)

(13)

(10)

220 (4)

(13)

(5)

(12)

220 (12) (11)

(2) (3)

220 (6)

(6)

(7)

9 VDC (15) 220 (2) (2) 4.7K(15) (7) (7) (6) 9 VDC (14) (5) 220 (3) (3)4.7K(14) (8) (8) (9) 9 VDC (13) (10) 220 (4) (4) 4.7K(13) (14) (14) (13) 9 VDC (12) (12) 220 (5) (1) (5) 4.7K(12) (1) (2) 9 VDC (11) (3) 220 (6) (6)4.7K (11) (7)

(5)

220 (10) (9)

9 VDC (7)4.7K (10)

(9) (10)

220

(6) (10) 220 (7)

(9)

9 VDC

(8) 4.7K(9)

(14)

(9) 220 (8)

9 VDC

(2)

(15)

(1) (1)4.7K(16)

220

(2)

(6)

(3)

(5)

220

(2) 4.7K(15) 9 VDC

(14) (3)4.7K(14)

(9)

(13)

(10)

220

(6) (14) 220 (3)

(9)

(13)

(12) (11)

(2)

9 VDC (1)

(5) 4.7K(12)

(5)

220

(7)

(8)

(13)

(2)

9 VDC

(1) (5) 4.7K(12)

9 VDC (6)4.7K(11)

(7)

(5)

9 VDC (7)4.7K (10)

(9) (10)

220

(8)

(6)

(7)

(13)

(1)

(8) 9 VDC

string pote ntiome te r

(9) 220 (8)

(8)4.7K(9)

(14)

(14) (12)

(2)

9 VDC (1) (1)4.7K(16)

(3)

220

(13) (16) 220 (1)

(12)

(1) (2)

9 VDC (3)

(2) (6)

(3)

(2) 4.7K(15)

(7)

(15) 220 (2) (7)

(5)

9 VDC (3)4.7K(14)

(9) (10)

220

(8)

(6) (14) 220 (3)

(5)

(8)

(9)

9 VDC (10)

(4) (13)

(5)

(4) 4.7K(13)

(14)

(12)

(2)

9 VDC (1) (5) 4.7K(12)

(13) (12) 220 (5)

(14) (12)

(2)

9 VDC (3)

(6)

(13) 220 (4)

(1)

(3)

220 (6) (7)

(7)

(6) 4.7K(11)

(11) 220 (6) (7)

(5)

220

(6) (5)

(8)

(10)

(8) (9)

(10)

5 VDC

(7) (5)

(5)

(10)

(11) 220 (6)

(10)

(12) (11)

(6) 4.7K(11)

(6) (10) 220 (7)

(9)

(8)

220

(11) 220 (6)

(12)

(1) (2)

(12)

9 VDC

(13) (12) 220 (5)

(3) (6)

(13) 220 (4) (14)

9 VDC

(6) (7)

(7) (5)

(4) 4.7K(13)

(3)

220

(15) 220 (2)

(8)

(9)

(14)

(12)

220 (12) (11)

220

(13) 220 (4)

(6) (14) 220 (3)

(10)

(5)

(13)

(3) (6)

(10)

220 (4)

(13)

(12) 220 (5)

(2)

(6) (7)

(7)

(1)

(3)

220

(15) 220 (2)

(14)

(12)

220

(3) 4.7K (14)

(9)

(13)

(14)

9 VDC (4) 4.7K(13)

(14)

9 VDC

(5)

(10) (4) (5)

(5)

220

220

(8)

(8)

9 VDC

(2) 4.7K(15)

(7)

(14)

(15) 9 VDC

(7)

(2)

(16)

(3)

(2)

(11)

(12)

(1)

(3)

(3)

(13) (16) 220 (1)

(16) 220 (1) (1) (3)

(6)

220

(14) (12)

220 (16)

(1) (1) 4.7K(16)

(2)

(10) (9)

(10) (13)

(7)

(3)

220

(4)

(5)

(8)

(8)

(8) (1)

(2)

(1) (3)

9 VDC

5 VDC

(16)

(2)

circuit

LM324 220

(16) 220 (1)

(15)

(11)

(2)

LED interface 14-bit flash ADC

(9)

(1)

241

buffer amplifier

input prote ction circuit

signa l ge ne ra tor input

(10)

6.4

buffer Schottky diode 4.7 VDC ze ne r diode

amplifer with input limit circuitry

Fig. 6.7 Circuit diagram for the KNH arrays. (left) Actual exertion array and (right) desired exertion array (Barrett and Bundle)

242

6 Embedded Systems Design

VDC

4V

LED light array on

0V t (s)

-8V 2s rest period

1s exercise period

total period = 3s waveform frequency = 1/total period = 0.33 cycles per second [Hz]

Fig. 6.8 KNH array settings. LEDs will illuminate for input voltages between 0 and 4 VDC. More LEDs incrementally illuminate as input voltage increases in response to signal generator input signal. The input to the array is protected by a 4.7 VDC zener diode and a Schottky diode to limit voltage input to levels between approximately 0 and 4.7 VDC (Barrett and Bundle)

6.4.3

Design Iteration II: Improved Features

Several years later, I (sfb) worked with graduate student Chris Sundberg on a revised visual feedback array design.3 We reported on this work in “Visual Feedback Array to Achieve Reproducible Limb Displacements and Velocities in Humans (Barrett and Sundberg 2017).” 4 We use this work for the ongoing case study of a microcontroller–based instrumentation system.

6.4.3.1 Background We modified the design of the original baseline array to increase portability, reduce cost and improve the ability to customize the desired protocol parameters. The new array design 3 Dr. Christopher Sundberg, Ph.D., Physical Therapy, College of Health Sciences, Marquette Uni-

versity. 4 Extracts from this article and related sources are used with permission of the Instrument Society of

America, Morgan and Claypool Publishers, and Springer Nature. References are provided at the end of the chapter.

6.4

Application: Visual Feedback Array

243

included an onboard microcontroller–based signal generator that eliminated the need for an external signal generator to interface and operate the array that depicts the imposed cadence. The complementary array that depicts the actual rate of displacement can be operated by any position transducer with an analog signal (e.g., string or rotary potentiometer, linear or rotary variable differential transformer, electrogoniometer, etc.). The array chassis hosts a 5 VDC power supply for the position transducer and onboard turn dials to adjust the desired offset and voltage ranges used to illuminate the 14 LEDs. All onboard adjustments for both array columns use 10 turn numerical dials with a locking mechanism that improves the ability to customize and ‘lock in’ desired protocol parameters.

6.4.3.2 Design Several enhancements were made to the original baseline design including: . An onboard, low cost microcontroller–based signal generator; . Preset signal generator settings for common rise and fall time settings of one and six seconds; . The ability to ‘lock’ the rise and fall time settings via mechanical lock configured potentiometers and a software based ‘lock/unlock’ feature; and . String pot compensation for a potentiometer not in the fully closed position when the client is at rest. The overall result was a fully self–contained system. Each enhancement will be discussed in turn. . Onboard signal generator. The early baseline version of the array required an external, low–frequency signal generator to provide the signal for the desired or imposed cadence (Barrett and Bundle). The external generator was replaced with a low cost (US $5), onboard microcontroller–based signal generator (Microchip ATmega168,5 www. microchip.com). The block diagram of the generator is provided in Fig. 6.9 (top). Inputs to the microcontroller include: lock, presets (1s or 6s), and fall and rise times. In response to these inputs, the microcontroller algorithm provides an 8–bit digital representation of the signal that is converted to a corresponding analog representation by an external 8– bit digital–to–analog converter (DAC) (Texas Instruments DAC0808, www.ti.com. The output of the DAC is fed to op amp based compensation circuitry to provide analog scale and DC offset features. A schematic representation is provided in Fig. 6.9 (bottom). The diagram of the signal generator’s algorithm activity is provided in Fig. 6.10. After startup configuration, the algorithm polls external control settings for assertion of the preset (‘1s’ or ‘6s’) switch settings. If in the ‘unlocked’ state and neither preset switch 5 The ATmega168 is in the same microcontroller family as the ATmega328–the host processor

onboard the Arduino UNO R3.

244

6 Embedded Systems Design

Fig. 6.9 Microcontroller–based signal generator (Barrett and Sundberg)

is asserted, then the settings from the rise and fall time potentiometers are read. If in the ‘locked’ state, a default 1s rise and fall time is employed. The algorithm for the ATmega168 was programmed in C. Preset signal generator settings. Over the course of a given study, common array settings are often repeatedly employed. For ease–of–use and repeatability, the array was equipped with a three position switch: ‘1s’ and ‘6s’ rise/fall time settings and ‘Manual’ for manual adjustment of the rise and fall time settings with the 10 turn potentiometers. When set for either ‘1s’ or ‘6s’, the microcontroller ignores the potentiometer rise and fall time settings

6.4

Application: Visual Feedback Array

245

Fig. 6.10 Microcontroller–based signal generator activity diagram (Barrett and Sundberg)

and generates a ramp signal with a preset one or six second rise/fall setting, respectively. When the switch is in the ‘Manual’ position and the ‘lock/unlock’ pushbutton is in the unlocked (depressed) position, the algorithm reads the rise and fall time settings from the 10 turn potentiometers. When the ‘lock/unlock’ pushbutton is in the locked (released) position, the rise and fall times are set and further changes to the rise and fall time potentiometers will not affect the signal generator output until the pushbutton is depressed back to the ‘unlocked’ position. This feature provides a stable setting by preventing inadvertent changes to the potentiometers. . String pot compensation. Ideally, no LEDs are illuminated in the initial rest limb position and all 14 LEDs are illuminated at the end of the desired range of motion. Without compensation, this would require the output voltage of the position transducer to always be 0 V in the initial position and 4 V at the end of the range of motion. However, due to variations both in experimental protocols and configurations of equipment setup, this is not always possible. Thus, the array is equipped with a compensation circuit (scale and offset) to adjust the voltage offset and range necessary for different experimental setups. Similar to the potentiometer controls for the onboard signal generator, the compensation

246

6 Embedded Systems Design

potentiometers are 10 turn dials with a mechanical locking mechanism. The compensation circuit is shown in Fig. 6.9 (bottom).

6.4.3.3 Results All array enhancements were fully tested and operated as intended on the assembled array as shown in Fig. 6.11. The results for the onboard microcontroller–based signal generator

Fig. 6.11 Microcontroller–based array

6.4

Application: Visual Feedback Array

247

Fig. 6.12 Microcontroller–based signal generator activity diagram (Barrett and Sundberg)

and preset signal settings are displayed in Fig. 6.12. The data were obtained using a DATAQ data logger (www.dataq.com). Figure 6.12A. shows the output from the signal generator with a ‘manual’ rise time of 2s and fall time of 4.5s achieved with the 10 turn rise and fall time potentiometers. Figure 6.12B. and C. illustrate the output from the preset signal generator settings with both the ‘1s’ and ‘6s’ rise/fall time settings. Data for the string pot compensation circuit are not shown but were tested under 20 different combinations of rest and fully extended positions.

6.4.4

Design Iteration III: Arduino–Based Design

I’ve (sfb) always wanted the opportunity to develop an Arduino–based version of the instrumentation array. The basic concept is illustrated in Fig. 6.13. In this design iteration, an Arduino ATmega2560 microcontroller is used as the host processor. The Arduino UNO R3 processor may also be used. We use the Adafruit ILI9341 full color TFT display discussed earlier in the book. This display has a 2.8 inch diagonal dimension and features 240 by

248

6 Embedded Systems Design +90 degrees

horizontal stationary strut bearing ring (between struts)

0 degrees

0 oA -t

DC d 5 V roun G

tX Ou

le ab ov m

ut str

-90 degrees

X

Fig. 6.13 Arduino–based instrumentation array

320 pixel resolution with 18-bit color. The display is used as a fully configured Arduino compatible shield. The display replaces the two column, 14 LED per column display. Due to its small size the display may be conveniently mounted close to the client on a bracket mounted to the exercise equipment. Desired settings (rise time, fall time, leg rest position, and desired leg maximum position) are set using a single ten turn potentiometer with a vernier dial and a single pushbutton switch. This is accomplished by sequentially cycling through the desired settings in the Arduino sketch. The actual position of leg elevation is measured using the CTi tilt sensor discussed

6.4

Application: Visual Feedback Array

249

earlier in the book. The circuit is powered by a commercially–off–the–shelf power supply or by a battery supply. We used a 9 VDC battery pack consisting of six alkaline AA 1.5 VDC batteries.

6.4.4.1 Algorithm Operation An Arduino sketch was created to gather appropriate data and display results on the TFT screen as a column of desired activity (red) and actual activity (green) as shown in Fig. 6.14. The UML activity diagram for the sketch is provided in Fig. 6.15.

Fig. 6.14 TFT instrumentation array

250

6 Embedded Systems Design

define variables and default values for: rise time, fall time, max angle, rest angle set pinMode initialize TFT generate initial TFT screen

TACT switch?

yes set times and angles

calculate rise, fall, and angle increment display up/down ramp

Fig. 6.15 Array UML

//******************************************************************* //KNH_array3 //Adapted from Adafruit GFX example //Written by Limor Fried/Ladyada for Adafruit Industries. //MIT license, all text above must be included in any redistribution // //Notes: //Provides two columns: // - Left: desired activity: provides red column of indicators // -Right: actual activity: provides green column of indicators //CTi tilt sensor analog output OUTX is connected to A0 //Ten turn potentiometer with vernier knob connected to A1 // //Adapted by: S. Barrett, June 1, 2023 //*******************************************************************

6.4

Application: Visual Feedback Array

251

//include files #include "SPI.h" #include "Adafruit_GFX.h" #include "Adafruit_ILI9341.h" #include #define #define #define #define #define unsigned unsigned unsigned unsigned unsigned unsigned unsigned

set_tact 8 TFT_DC 9 TFT_CS 10 tilt_sensor A0 adjust_pot A1

//set tact switch //Adafruit shield DC, CS //default setting //tilt sensor //adjustment pot //global variables

int int int int int int int

x1, y1, x2, y2; width, height; rise_time = 1, fall_time = 1; //default values goal_angle = 75, rest_angle = 0; rise_time_inc, fall_time_inc, angle_inc; circle_diam, num_circles, num_circles_cnt; tilt_angle; //tilt sensor value //hardware UNO SPI:#13, #12, #11 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC); void setup() { pinMode(set_tact, OUTPUT); tft.begin(); width = tft.width(), height = tft.height(); testFillScreen(); delay(500); testLines(ILI9341_GREEN); delay(500); }

//initialize TFT display

//format screen

void loop(void) { //read tact switch - if low go to set_rise_fall //press and hold switch if(digitalRead(set_tact)) { delay(50); //sw debounce set_times_angles(); } rise_time_inc = (unsigned int)((rise_time*1000)/15); //delay in ms fall_time_inc = (unsigned int)((fall_time*1000)/15); //delay in ms angle_inc = (unsigned int)((goal_angle-rest_angle)/15); //incr angle display_up_down_ramp(); //display up/dowm ramp delay(100); }

252

6 Embedded Systems Design

//******************************************************************* unsigned long testFillScreen() { tft.fillScreen(ILI9341_BLACK); unsigned long start = micros(); tft.fillScreen(ILI9341_BLACK); tft.setCursor(0,0); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(2); tft.print("Rise:"); tft.println(rise_time, DEC); tft.print("Fall:"); tft.println(fall_time, DEC); tft.setCursor(width/2,0); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(2); tft.print("Goal:"); tft.println(goal_angle, DEC); tft.setCursor(width/2,15); tft.print("Rest:"); tft.println(rest_angle, DEC); return micros() - start; }

//display settings

//******************************************************************* unsigned long testLines(uint16_t color) { unsigned long start, t; start = micros(); //draw crosshairs tft.drawLine(width/4, 30, width/4, height, ILI9341_GREEN); tft.drawLine(width*3/4, 30, width*3/4, height, ILI9341_GREEN); //draw circles circle_diam = (height-30)/15;

//15 gaps between LEDs

for(unsigned int circle_y = height-15; circle_y >= 25+circle_diam ; circle_y = circle_y - circle_diam) { tft.fillCircle(width/4, circle_y, circle_diam/2, ILI9341_RED); } for(unsigned int circle_y = height-15; circle_y >= 25+circle_diam ; circle_y = circle_y - circle_diam) { tft.fillCircle(width*3/4, circle_y, circle_diam/2, ILI9341_GREEN); } t = micros() - start; // fillScreen doesn’t count against timing

6.4

Application: Visual Feedback Array

yield(); return micros() - start; } //******************************************************************* void set_times_angles(void) { unsigned long start, t; start = micros(); unsigned int analog_value; Serial.println("Set up down time..."); //continue to hold switch while setting rise time on pot //release switch when desired value is selected while(digitalRead(set_tact)) { Serial.println("set rise time..."); analog_value = analogRead(adjust_pot); rise_time = map(analog_value, 0, 1023, 0, 10); Serial.print("Rise:"); Serial.println(rise_time); tft.print("Rise:"); tft.println(rise_time, DEC); testFillScreen(); testLines(ILI9341_GREEN); delay(100); } delay(3000); //continue to hold switch while setting fall time on pot //release switch when desired value is selected while(digitalRead(set_tact)) { Serial.println("set fall time..."); analog_value = analogRead(adjust_pot); fall_time = map(analog_value, 0, 1023, 0, 10); Serial.print("Fall:"); Serial.println(fall_time); tft.print("Fall:"); tft.println(fall_time, DEC); testFillScreen(); testLines(ILI9341_GREEN); delay(100); } delay(3000); //continue to hold switch while goal angle on pot //release switch when desired value is selected while(digitalRead(set_tact))

253

254

6 Embedded Systems Design

{ Serial.println("set goal angle..."); analog_value = analogRead(adjust_pot); goal_angle = map(analog_value, 0, 1023, 0, 90); Serial.print("Goal:"); Serial.println(goal_angle); tft.setCursor(width/2,0); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(2); tft.print("Goal:"); tft.println(goal_angle, DEC); testFillScreen(); testLines(ILI9341_GREEN); delay(100); } delay(3000); //continue to hold switch while rest angle on pot //release switch when desired value is selected while(digitalRead(set_tact)) { Serial.println("set rest angle..."); analog_value = analogRead(adjust_pot); rest_angle = map(analog_value, 0, 1023, 0, 90); Serial.print("Rest:"); Serial.println(rest_angle); tft.setCursor(width/2,15); tft.setTextColor(ILI9341_GREEN); tft.setTextSize(2); tft.print("Rest:"); tft.println(rest_angle, DEC); testFillScreen(); testLines(ILI9341_GREEN); delay(100); } return micros() - start; } //******************************************************************* void display_up_down_ramp(void) { unsigned long start, t; start = micros(); //draw crosshairs tft.drawLine(width/4, 30, width/4, height, ILI9341_GREEN); tft.drawLine(width*3/4, 30, width*3/4, height, ILI9341_GREEN); //draw circles //clear display circle_diam = (height-30)/15;

//15 gaps between indicators

6.4

Application: Visual Feedback Array

255

//blank desired and actual column with black circles for(unsigned int circle_y = height-15; circle_y >= 25+circle_diam ; circle_y = circle_y - circle_diam) { //desired tft.fillCircle(width/4, circle_y, circle_diam/2, ILI9341_BLACK); //actual tft.fillCircle(width*3/4, circle_y, circle_diam/2, ILI9341_BLACK); } //desired and actual going up //plot desired is red circle_diam = (height-30)/15; //15 gaps between LEDs num_circles_cnt = 0; for(unsigned int circle_y = height-15; circle_y >= 25+circle_diam ; circle_y = circle_y - circle_diam) { //desired tft.fillCircle(width/4, circle_y, circle_diam/2, ILI9341_RED); //actual //read tilt sensor tilt_angle = read_tilt_angle(); num_circles = (unsigned int) ((tilt_angle - rest_angle)/angle_inc); if(num_circles >= num_circles_cnt) tft.fillCircle(width*3/4, circle_y, circle_diam/2, ILI9341_GREEN); num_circles_cnt++; delay(rise_time_inc); } //desired and actual going down circle_diam = (height-30)/15; //15 gaps between LEDs for(unsigned int circle_y = 39; circle_y

5

Shift right

&

8

Bitwise AND

^ |

8 8

Bitwise exclusive OR Bitwise OR

Description

Unary Operations Symbol

Precedence

Description

!

2

Unary negative

~

2

One’s complement (bit-by-bit inversion)

++

2

Increment

-type(argument)

2

Decrement

2

Casting operator (data type conversion)

Fig. B.5 C operators (continued). (Adapted from (Barrett and Pack))

B.3.1.1 General Operations Within the general operations category are brackets, parenthesis, and the assignment operator. We have seen in an earlier example how bracket pairs are used to indicate the beginning and end of the main program or a function. They are also used to group statements in programming constructs and decision processing constructs. This is discussed in the next several sections. The parenthesis is used to boost the priority of an operator. For example, in the mathematical expression .7 x 3 + 10, the multiplication operation is performed before the addition since it has a higher precedence. Parenthesis may be used to boost the precedence of the addition operation. If we contain the addition operation within parenthesis, .7 x (3 + 10), the addition will be performed before the multiplication operation and yield a different result from the earlier expression. The assignment operator (.=) is used to assign the argument(s) on the right–hand side of an equation to the left–hand side variable. It is important to insure the left and the right–hand side of the equation have the same type of arguments. If not, unpredictable results may occur.

278

Appendix B: Programming in C with the Microchip ATmega328

B.3.1.2 Arithmetic Operations The arithmetic operations provide for basic math operations using the various variables described in the previous section. As described in the previous section, the assignment operator (.=) is used to assign the argument(s) on the right–hand side of an equation to the left–hand side variable. Example: In this example, a function returns the sum of two unsigned int variables passed to the function. unsigned int { unsigned int

sum_two(unsigned int variable1, unsigned int variable2) sum;

sum = variable1 + variable2; return sum; }

B.3.1.3 Logical Operations The logical operators provide Boolean logic operations. They can be viewed as comparison operators. One argument is compared against another using the logical operator provided. The result is returned as a logic value of one (1, true, high) or zero (0, false, low). The logical operators are used extensively in program constructs and decision processing operations to be discussed in the next several sections.

B.3.1.4 Bit Manipulation Operations There are two general types of operations in the bit manipulation category: shifting operations and bitwise operations. Let’s examine several examples: Example: Given the following code segment, what will the value of variable2 be after execution? unsigned char unsigned char

variable1 = 0x73; variable2;

variable2 = variable1 New . − > Project. − > GCC Executable Project. − > . • If using the gcc compiler: Write program • If using the gcc compiler: Build program • Tools . − > Device Programming – – – –

Insure target chip has 5 VDC applied STK500 (Simulator) ATmega328 . − > Apply Device Signature . − > Read

• Memories: Flash: Program–Browse for desired “filename.hex” and press “Program.” • Fuses: Choose description that best matches your time base choice: internal or external oscillator and clock speed range. . − > Program

B.5

Example: ATmega328 Testbench

In this example, we present the hardware configuration of a barebones Testbench and a basic software framework to get the system up and operating. The purpose of the Testbench is to illustrate the operation of selected ATmega328 subsystems working with various I/O devices. More importantly, the Testbench will serve as a template to develop your own applications.

B.5.1

Hardware Configuration

Provided in Fig. B.8 is the basic hardware configuration for the Testbench. PORTB is configured with eight tact (momentary) switches with accompanying debouncing hardware. PORTD is equipped with an eight–channel tristate LED indicator. For a given port pin, the green LED will illuminate for a logic high, the red LED for a logic low, and no LEDs for a tristate high–impedance state. Aside from the input hardware on PORTB and the output display hardware on PORTD of the controller, there are power (pins 7, 20, and 21) and ground (pins 8 and 22) connections. A standard 5–VDC power supply may be used for the power connections. For portable applications, a 9–VDC battery equipped with a 5–VDC regulator (LM340–05 or uA7805)

288

Appendix B: Programming in C with the Microchip ATmega328 ISP connector to AVR Dragon VTG (to Vcc) MISO 1 MOSI SCK GND /RST

VDD

PD0

47

G

PD1

47

G

PD2

47

R

R

1M

1.0 uF

sys reset

G R

PD3

47

G

PD4

47

G

PD5

47

G

R VDD

R

ZTT 10MHz resonator

R

47 PD6

VDD = 5 VDC 74HC14

4.7K

R

to PB0 SW0

470K

47 PD7

5 VDC voltage regulator

0.1 uF 9 VDC

0.1 µF

0.1 µF

Vcc

Vcc ground

3.0 K

74HC14 to PB5

SW5

G R

5 VDC

7805

VDD = 5 VDC 4.7K

G

470K

2N2222

+ LM324

2N2907

3.0 K

0.1 uF

Fig. B.8 ATmega328 Testbench hardware

may be used as a power source. The RESET pin (pin 1) has a resistor (1 M.Ω), two capacitors (1.0 .µF), and a tact switch configured to provide a reset switch for the microcontroller. We use a ZTT 10–MHz ceramic resonator as the time base for the Testbench. It is connected to pins 9 (XTAL1) and 10 (XTAL2) of the ATmega328. Hardware interface details of the Testbench are provided in “Arduino I: Getting Started!”

B.5.2

Software Configuration

The Testbench software is provided below. The program contains the following sections: • Comments • Include Files: We have included the Atmel AVR Studio include file for the ATmega (avr/io.h). This file provides the software link between the names of the ATmega328 hardware registers and the actual hardware locations. When a register is used by name in the program, reference is made to the contents of that register. • Function Prototypes • Global Variables

Appendix B: Programming in C with the Microchip ATmega328

289

• Main Program: We begin the main program by calling the function to initialize the ports and then enter a continuous loop. Within the loop body, the ATmega328 monitors for a status change on PORTB. When the user depresses one of the tact switches connected to PORTB, a change of status is detected and the appropriate LED is illuminated on PORTD. • Function Definition

//***************************************************************** //file name: testbench.c //function: test bench for MICROCHIP AVR ATmega328 controller //target controller: MICROCHIP ATmega328 // //MICROCHIP AVR ATmega328 Controller Pin Assignments //Chip Port Function I/O Source/Dest Asserted Notes //Pin 1 PC6 /Reset pushbutton circuitry //Pin 2 PD0 to tristate LED indicator //Pin 3 PD1 to tristate LED indicator //Pin 4 PD4 to tristate LED indicator //Pin 5 PD3 to tristate LED indicator //Pin 6 PD4 to tristate LED indicator //Pin 7 VCC to 5 VDC //Pin 8 GND to GND //Pin 9 PB6 ZTT 10 MHz ceramic resonator //Pin 10 PB7 ZTT 10 MHz ceramic resonator //Pin 12 PD6 to tristate LED indicator //Pin 13 PD7 to tristate LED indicator //Pin 14 PB0 to active high RC debounced switch //Pin 15 PB1 to active high RC debounced switch //Pin 16 PB2 to active high RC debounced switch //Pin 17 PB3 to active high RC debounced switch //Pin 18 PB4 to active high RC debounced switch //Pin 19 PB5 to active high RC debounced switch //Pin 20 AVCC to 5 VDC //Pin 21 AREF to 5 VDC //Pin 22 GND to GND //Pin 23 PC0 //Pin 24 PC1 //Pin 25 PC2 //Pin 26 PC3 //Pin 27 PC4 //Pin 28 PC5 //***************************************************************** //Include Files: choose the appropriate include file depending on //the compiler in use comment out the include file not in use.

290

Appendix B: Programming in C with the Microchip ATmega328

//include file(s) for the Atmel Studio gcc compiler #include //contains reg definitions

//function prototypes********************************************** void initialize_ports(void);

//initializes ports

//main program***************************************************** //global variables unsigned char old_PORTB = 0x00; //present value of PORTB unsigned char new_PORTB; //new values of PORTB void main(void) { initialize_ports(); while(1) { //main loop new_PORTB = PINB;

//initialize ports

//read PORTB

if(new_PORTB != old_PORTB){ switch(new_PORTB){

//process change //in PORTB input //PORTB asserted high

case 0x01: PORTD=0x00; PORTD=0x01; break;

//PB0 (0000_0001) //turn off all LEDs PORTD //turn on PD0 LED (0000_0001)

case 0x02: PORTD=0x00; PORTD=0x02; break;

//PB1 (0000_0010) //turn off all LEDs PORTD //turn on PD1 LED (0000_0010)

case 0x04: PORTD=0x00; PORTD=0x04; break;

//PB2 (0000_0100) //turn off all LEDs PORTD //turn on PD2 LED (0000_0100)

case 0x08: PORTD=0x00; PORTD=0x08; break;

//PB3 (0000_1000) //turn off all LEDs PORTD //turn on PD3 LED (0000_1000)

case 0x10: PORTD=0x00; PORTD=0x10;

//PB4 (0001_0000) //turn off all LEDs PORTD //turn on PD4 LED (0001_0000)

Appendix B: Programming in C with the Microchip ATmega328

291

break; case 0x20: PORTD=0x00; PORTD=0x20; break;

//PB5 (0010_0000) //turn off all LEDs PORTD //turn on PD5 LED (0010_0000)

default:; }

//all other cases //end switch(new_PORTB) //end if new_PORTB

} old_PORTB=new_PORTB; } }

//update PORTB //end while(1) //end main

//***************************************************************** //initialize_ports: provides initial configuration for I/O ports //***************************************************************** void initialize_ports(void) { DDRB=0x00; PORTB=0x00;

DDRC=0xff; PORTC=0x00;

//PORTB[7:0] as input //disable PORTB //pull-up resistors //set PORTC as output //initialize low

DDRD=0xff; //set PORTD as output PORTD=0x00; //initialize low } //*****************************************************************

B.6

Example: Rain Gauge Indicator

In this example we program a rain gauge indicator using the testbench hardware LEDs on PORTD. LEDs are sequentially illuminated with a one second delay between PORTD changes. We use a simple, yet inaccurate method to generate the delay. We provide a more sophisticated and accurate method using interrupts in an upcoming chapter. //***************************************************************** //Rain Gauge //***************************************************************** //function prototypes**********************************************

292

Appendix B: Programming in C with the Microchip ATmega328

void initialize_ports(void); void delay_100ms(void); void delay_1s(void);

//initializes ports

//Include Files: choose the appropriate include file depending on //the compiler in use comment out the include file not in use.

//include file(s) for the Microchip Studio gcc compiler #include //contains reg definitions

int main(void) { unsigned char count = 0; initialize_ports(); for(count { PORTD = PORTD = PORTD = PORTD = PORTD = PORTD = PORTD = PORTD = PORTD = PORTD = } }

= 0; count