Вы находитесь на странице: 1из 85

아두이노 기초 및 Matlab/Simulink 연동

김정수

서울과학기술대학교 전기정보공학과
http://sites.google.com/site/cdslweb

1
아두이노

https://www.arduino.cc/

2
아두이노 핀 배치

3
Arduino Uno

-Microcontroller ATmega328
-Operating Voltage 5V
-Input Voltage 7-12V
-Input Voltage (limits) 6-20V
-Digital I/O Pins 14
(of which 6 provide PWM output)
-Analog Input Pins 6
-DC Current per I/O Pin 40 mA
-DC Current for 3.3V Pin 50 mA
-Flash Memory 32 KB
(ATmega328) of which
0.5 KB used by bootloader
-SRAM 2 KB (ATmega328)
-EEPROM 1 KB (ATmega328)
-Clock Speed 16 MHz

4
Arduino Variants
Arduino hardware

5
Arduino Development Environment

6
Arduino Development Environment

1. Project or code
2. Compile
3. Program download(ISP)
4. Console monitor

7
Arduino Development Environment
• http://arduino.cc/en/Main/Software
• Connect PC with Arduino
• Install the driver
– New device message
– Window Start > Control Pannel > Device
– Select “Port” from devicelist",
"Arduino UNO (COMxx)“
– Click the right button and select “driver update”
– Select “drivers” folder in arduino-00xx folder

8
아두이노 개발 환경 설치
• http://arduino.cc/en/Main/Software
• PC 아두이노에 연결하기
• 드라이버 설치하기
– 새 장치 발견 메시지
– 윈도우 시작 > 제어판 > 장치 관리자
– 장치리스트에서 "포트"를 선택하면,
"Arduino UNO (COMxx)“
– 해당장치를 우측버튼으로 클릭한 뒤
"드라이버 업데이트"를 선택
– arduino-00xx 폴더내에 있는 drivers 폴더를 선택

9
Arduino Development Environment

10
Arduino Development Environment

11
Arduino Development Environment Setup

Sketch Environment
• Run arduino.exe

Board selection COM-port setup

12
Digital Pin Control
• Digital pin
- Pin 0~13 (Arduino UNO)
- 0V(off, LOW, 0), 5V(on, HIGH, 1) output/input

• Control digital pin


- Digital pin initilization : pinMode(pinNumber, mode)
- Digital pin read : digitalRead(pinNumber)
on, off = 5V, 0V = HIGH, LOW
- Digital pin write : digitalWrite(pinNumber, state)
on, off = 5V, 0V = HIGH, LOW

• Digital pins with special functions


- Pin 0, 1: reserved for hardware serial pin
- Pin 3, 5, 6, 9, 10, 11: PWM (UNO board has ~ symbol)
- Pin 10, 11, 12, 13: SPI pin (SS, MOSI, MISO, SCK)

13
Ex1: LED blink
% Code upload
compile
/*
Turns on an LED on for one second, then off
for one second, repeatedly.
This example code is in the public domain.
*/
void setup() {
// initialize the digital pin as an output.
// Pin 13 has an LED connected on Arduino
boards:
pinMode(13, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(13, LOW); // set the LED off
delay(1000); // wait for a second
}

14
Structure of the Arduino Program
• Basic grammar is the same as C language
• http://arduino.cc/en/Reference/HomePage
• http://arduino.cc/en/Tutorial/HomePage
Global variables and user defined functions

void setup() {
- Board pin and register configuration
pinMode(13, OUTPUT);
} - Set Pin 13 as output port
void loop() {
digitalWrite(13, HIGH);
- Main part of the program
delay(1000); - This part is run repeated forever
digitalWrite(13, LOW); - Write 1,0 on Pin 13 repeatedly
delay(1000);
}
void setup() { }
Basic structure
void loop() { }
15
Ex2: External LED Turn on/off (digital output)
• 하드웨어 설정
void setup() {
pinMode(10, OUTPUT);
}

void loop() {
digitalWrite(10, HIGH);
delay(1000);
digitalWrite(10, LOW);
delay(1000);
}

16
Toggle Switch

• 실제 터미널 A,D 그리고 B,C는 항상 연결되어 있음.


• 스위치를 누르면 AD와 BC가 연결됨.

17
Toggle Switch with Arduino

• 디지털 입력은 0V와5V 사이에서 일


정한 값을 가지지 못함(floating)
• Pull-up Register (5V에 연결)
• Pull-down Register (GND에 연결)
입력핀을 5V 또는0V 연결할 때 적용
• 스위치연결방식
• 스위치동작 (우측 그림 참조)
– 스위치를 닫히면 HIGH
– 스위치가 열리면 LOW

18
Ex3: Switch test (digital input)
• Hardware setup
void setup() {
Serial.begin(9600);
pinMode(13, INPUT_PULLUP);
}

void loop(){
GND
int sw=0;
sw = digitalRead(13);
13 Serial.println(sw);
delay(200);

In fact, you have to have a resistor.


Arduino has an internal resistor.
19
Ex3: Switch test (digital input)

void setup() {
Serial.begin(9600); // 시리얼 통신 설정

pinMode(13, INPUT_PULLUP); // 13번 핀을 디지털 입력으로 설정함.


}

void loop(){
int sw=0;
sw = digitalRead(13); // 13번 핀 값을 읽어서 변수 sw에 저장
Serial.println(sw); // sw 값을 serial로 보냄.
delay(200);

20
pinMode in Arduino
• 함수 설명
특정 핀을 입력 또는 출력으로 쓸지 설정하는 함수
• 함수 사용법
pinMode(핀번호, 사용 방법)
• Mode
– INPUT: 디지털 입력으로 사용함을 의미
– INPUT_PULLUP: 디지털 입력으로 사용함을 의미하며 아무것도 연결
되지 않았다면 내부 저항을 이용하여 HIGH 상태로 PULLUP 시켜두
라는 것을 의미
– OUTPUT: 디지털 출력으로 사용함을 의미

21
Ex4: Switch + LED
void loop() {
const int LED = 10;
val = digitalRead(BUTTON);
const int BUTTON = 13;
if ((val == 0) && (old_val ==1) )
{
int val = 1;
state=1-state;
int old_val = 1;
delay(10);
int state = 1;
}
old_val=val;
void setup() {
if (state==0)
pinMode(LED,OUTPUT);
{
pinMode(BUTTON,INPUT_PULLUP);
// be careful!! pressed =0, unpressed =1 digitalWrite(LED,1);
} }
else
{
digitalWrite(LED,0);
}
}

22
Exercise
• Exercise
– Connect two switches
– When one switch is turned on, the LED is turned on
– When the other switch is turned on, the LED is turned off

23
아두이노 아날로그 입력 (analogRead())
• 아두이노 우노의 A0~ A5까지 6개의 핀을 이용하여 아날로
그 입력을 처리함.
• 디지털 입출력은 0과 1만 처리하지만 아날로그 핀은
analogRead()함수를 이용하여 읽어 들인 전압을 0~1023 의
정수값으로 변환하여 처리함.
(분해능은 0.0049V (4.9mV = 5V/1024))
• analogRead()
입력 인수로 0(또는 A0), 1(또는 A1), … 5(또는 A5)를 주고 리
턴값은 int형으로서 앞에서 언급한 대로 0~1023 값

24
아두이노 아날로그 출력: analogWrite()
• 아날로그 출력은 1byte = 8bit = 256 즉 0~255의 값을 출력
• 아날로그 출력핀에 연결된 출력(기본적으로 led 나 모터 등
등)은 255단계의 밝기나 세기를 조절할 수 있음
• 이러한 출력을 만들기 위하여 아두이노는 PWM (Pulse
Width Modulation)을 이용함.
• 아두이노에서 PWM 기능을 가진 핀은 앞에 (~) 물결 마크가
붙어 있음.
• 아두이노 우노에서는 3, 5, 6, 9, 10, 11번 핀이 PWM 핀임
• analogWrite(핀번호, PWM ratio)
PWM ratio: 0~255

25
아두이노 아날로그 출력: PWM

 출력은 1.25V

 출력은 2.5V

 출력은 3.75V

• analogWrite(3,127)은 50% duty ratio 의미

26
Ex1: Variable Resistor (analog input)

27
Ex1: Variable Resistor (analog input)

void setup() {
pinMode(A0, INPUT);
pinMode(10, OUTPUT);
}

void loop() {
int analogInput = analogRead(A0);
int brightness = analogInput /4; // analog input value(0-1023)
analogWrite(10, brightness);
}
Arduino has an internal ADC

28
Ex2: LED Brightness Control (analog output)

int i=0;
void setup() {
pinMode(10, OUTPUT);
}
void loop() {
for(i=1;i<255;i++) // analog output value(0-255)
{
analogWrite(10,i); // PWM (Pulse Width Modulation)
delay(10);
}
for(i=255;i>0;i--)
{
analogWrite(10,i);
delay(10);
}
}

29
7 세그먼트

5번 핀
high로
해야

3, 8번은 GND (Ground)


30
Exercise
• Exercise 1 void setup()
{
Change the brightness of a LED Serial.begin(9600);
using a variable resistor pinMode(10,INPUT)

}
void loop()
{
int reading = analogRead(10);
Serial.println(reading);
delay(500);
• Exercise 2 }
Read the variable resistor and denote its level on the
seven segment.
• Exercise 3
Visit http://goo.gl/kLtNmg and try a sensor on the list.
31
아두이노 시리얼 통신
• 시리얼통신(직렬 통신)은 1번에 1비트씩 데이터를 송수신
• 패럴렐 통신(병렬 통신)은 1번에 8비트씩 데이터를 송수신
• 시리얼 통신을 하는 기기들간에는 통신 속도가 같아야 함
• 시리얼 통신의 속도는 300, 600, 1200, 2400, 4800, 9600,
14400, 19200, 28800, 38400, 57600, 115200 (Baud Rate)으
로 설정이 가능함
• 아두이노 시리얼 핀

32
아두이노 시리얼 통신
• 디지털 0번 RXD (Receive Data) 데이터 수신
• 디지털 1번 TXD (Transmit Data) 데이터 송신
• 스케치를 이용한 통신 속도 조절
• 시리얼 통신에는 UART(RS232-C),
I2C, SPI, CAN 등
• 이러한 통신방법을 이용해
WiFi나 Bluetooth, Xbee같은
통신규약을 이용

33
아두이노 시리얼 통신 함수
• Serial.begin(speed) : 시리얼 통신의 속도 조절. 매개변수
speed에 정해진 Baud Rate (초당 전송받는 비트 수) 값을 입
력.
• Serial.available() : 시리얼 통신으로 데이터를 받았는지 확
인. 받았다면 데이터 수를 반환. 받지 않았다면 0을 반환.
(반환≠출력)
• Serial.read() : 수신받은 데이터를 한개씩 읽어와 저장.
• Serial.println(value) 또는 Serial.print(value) : value 값을
출력. value에는 문자나 숫자, 문자열 등이 올 수 있음

34
아두이노 시리얼 통신 예제
const int SENS_PIN = A0;
아날로그 핀으로 센서 값을 입력받고, 그
const int LED_PIN = 13;
값을 시리얼 통신으로 출력해주는 프로그램
int sensorValue = 0;
boolean toggle = true;
void setup() {
Serial.begin(9600); //시리얼 통신의 속도를 9600 Baud Rate로 설정한다.
}
void loop() {
if (Serial.available()) { //만약 ((시리얼통신) 데이터 값을 받았다면)
Serial.read(); // (시리얼통신) 데이터값을 읽고 저장
sensorValue = analogRead(SENS_PIN);
Serial.println(sensorValue); //시리얼모니터에 값(sensorValue)을 출력한 후 줄바꿈해줌.
digitalWrite(LED_PIN, toggle); // toggle the LED
toggle = !toggle;
}
} 메카솔루션 오픈랩

35
아두이노 시리얼 응용: 블루투스 연결
• const int SENS_PIN = A0;
const int LED_PIN = 13;
int sensorValue = 0;
boolean toggle = true;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available()) {
Serial.read();
sensorValue = analogRead(SENS_PIN);
Serial.println(sensorValue);
digitalWrite(LED_PIN, toggle); // toggle
the LED 안드로이드 폰 설정 및 확인
toggle = !toggle; http://blog.naver.com/roboholic84/
220317084894
} 참고: 메카솔루션 오픈랩
}
36
Polling and Interrupt
Suppose that a pre-defined task needs to be done when an
input enters through pin i but we do not know when it occurs
• Polling approach
Only look at pin i and
do not any other task. pin i
When an input enters,
the task is done
• Interrupt approach
Do other tasks (do not care about pin i) and
do the pre-defined task when an input enters.

37
Polling and Interrupt
• Polling • Interrupt

Task Task
execution execution

Task Task
execution execution
Task
execution

Task
execution Task
execution

38
Ex: LED Blink - Polling
const int swPin = 2;
const int ledPin = 12;
int btnState = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(swPin, INPUT);
}
void loop(){
btnState = digitalRead(swPin); Monitoring the input
if (btnState == HIGH) { pin continuously
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}

39
Ex: LED Blink - Interrupt
boolean ledflag = LOW;
void setup() {
pinMode(12,OUTPUT);
pinMode(2,INPUT);
attachInterrupt(0,int_led,FALLING);
// attachInterrupt(interrupt number,ISR,trigering type);
// ISR: Interrupt Service Routine Declation
digitalWrite(12,LOW); }
// Do not care about the input pin !!
void loop() {

}
// ISR (Interrupt Service Routine)
void int_led(){
ledflag=!ledflag;
digitalWrite(12,ledflag);
}

40
Interrupt
• UNO has 2 interrupts: INT0-Pin2, INT1-Pin3

• LOW to trigger the interrupt whenever the pin is low,


• CHANGE to trigger the interrupt whenever the pin
changes value
• RISING to trigger when the pin goes from low to high,
• FALLING for when the pin goes from high to low.
41
인터럽트
• 아두이노 보드들의 인터럽트 핀 배치

• 인터럽트 ISR을 선언할 때는 인터럽트 번호를 사용함.

42
인터럽트 주의 사항[5]
• 인터럽트 ISR에는 파라미터를 전달하거나 리턴할 수 없음.
void xxx_callback() 형태가 됩니다.
• ISR 안에서는 delay() 함수를 사용할 수 없음
• milli-단위의 시각을 가져오는 함수인 millis() 를 사용하더라도 값이 증가
하지 않음. delayMicroseconds() 의 경우에는 인터럽트에 독립적이므로
정상 동작함
• ISR 안에서 Serial data를 읽을 경우 값이 소실됨.
• ISR 안에서 수정되는 전역 변수는 volatile 로 선언되어야 함
• ISR 은 최대한 짧고 빠르게 수행되도록 작성해야 함.
• 여러개의 ISR이 등록되어 있더라도 동시에 수행되지는 않음.
• 블루투스 모듈과의 통신을 위해 주로 사용되는 SoftwareSerial 라이브러
리의 경우 내부적으로 인터럽트를 사용하는 것으로 알려져 있으므로
UNO 보드의 경우 D2, D3 에 연결해야만 정상동작 합함. 이를 회피하기
위해서 D0, D1 핀에 연결해서 Hardware Serial 로 동작시킬 수 있음.
43
아두이노 타이머
• delay(), millis(), micros(), delayMicroseconds(), PWM 함수
인 analogWrite() 및 tone(), noTone() 함수들 및 서보모터
라이브러리 등이 내부적으로는 타이머를 사용
• 아두이노는 3개의 타이머 보유
• Timer 0는 8비트, Timer 1은 16비트, Timer 2는 8비트임
• 타이머 레지스터 변경을 통해 타이머 제어 가능함

44
아두이노 타이머[5]

• TCNTx - Timer/Counter Register. 타이머 동작 값 저장.


• OCRx - Output Compare Register
• ICRx - Input Capture Register (16비트 타이머용)
• TIMSKx - Timer/Counter Interrupt Mask Register. 타이머 인터럽트 활
성화/비활성화 용도
• TIFRx - Timer/Counter Interrupt Flag Register. pending timer interrupt
용도인지 표시

45
아두이노 타이머: 동작 클럭과 타이머 주기
• CPU 동작 주기 = 16MHz
• 최대 타이머 카운트 (8비트는 256, 16비트는 65536)
• CPU 주기를 선택한 prescaler 로 나눔 (16000000 / 256 =
62500)
• 결과값을 다시 원하는 주기로 나눔 (62500 / 2Hz = 31250)
• 결과값을 최대 카이머 카운트와 비교 (31250 < 65536 : 적
합). 적합하지 않은 경우 더 큰 prescaler를 선택함

46
예제: 타이머 레지스터 직접 제어
#define ledPin 13
http://www.letmakerobots.com/node/28278
void setup() {
pinMode(ledPin, OUTPUT);
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts

}
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{ digitalWrite(ledPin, digitalRead(ledPin) ^ 1); // toggle LED pin }
void loop() { // your program here... }

47
Timer Interrupt
• Do task timely (eg, do something at every 20 ms)
• Possible to control timer register in CPU but not easy
• Several libraries to help access the registers
• Download the library
http://www.pjrc.com/teensy/arduino_libraries/MsTimer2.zip
• Install the library
http://www.hardcopyworld.com/ngine/aduino/index.php/archives/981

• 3 functions
– MsTimer2::set(ms, ISR)
– MsTimer2::start()
– MsTimer2::stop()

48
Ex: Timer Interrupt
#include <MsTimer2.h>

void flash() {
static boolean output = HIGH;
digitalWrite(12, output);
output = !output;
}

void setup() {
pinMode(12, OUTPUT);
MsTimer2::set(500, flash); // call function flash at every 500ms
MsTimer2::start();
}

void loop() {
}

49
Arduino + Matlab 연동하기 (R2012 경우 )
1. ArduinoIO.zip를 다운 받아서 내 컴퓨터의 적절한 곳에 압축을 푼다. 여기서는
D:\arduino\ArduinoIO라고 가정한다
2. 아두이노를 PC에 연결한다. (COM port 확인 포함)
3. 스케치에서 D:\arduino\ArduinoIO\pde\adio\adio.pde를 불러서 확인후
아두이노에 업로드한다.
4. Matlab에서 D:\arduino\ArduinoIO를 path에 포함시킨다. (setpath 이용)
5. 아두이노와 Matlab 연결확인을 위해서 다음을 실행한다
>> a=arduino('COM3') (COM 다음 숫자는 본인에 맞게)
6. Attempting connection .............
Basic Analog and Digital I/O (adio.pde) sketch detected
Arduino successfully connected !

ArduinoIO.zip 다운로드
http://www.mathworks.com/matlabcentral/fileexchange/32374
50
Arduino + Matlab 연동하기

• Matlab에서 아두이노 시작하기


https://www.mathworks.com/help/supportpkg/arduinoi
o/ref/arduino.html

• Matlab에서 아두이노 함수
https://www.mathworks.com/help/supportpkg/arduinoi
o/functionlist.html

51
Arduino + Matlab 연동하기
• 시작

52
Ex1: Check Connection
>> a=arduino(‘com3’,’uno’);
>> writeDigitalPin(a,’D13’,0); Matlab은 interpreter
>> writeDigitalPin(a,’D13’,1);
방식이므로 한줄씩
실행이 됨
>> writeDigitalPin(a,’D13’,0);
>> writeDigitalPin(a,’D13’,1);
>> writeDigitalPin(a,’D13’,0);
>>clear a

53
Ex2: Turn on a LED using Matlab
% Edit the following in Matlab editor
% test_led.m
a=arduino(‘com3’,’uno’);
for i = 1:10
writeDigitalPin(a,’D13’,1);
pause(0.5);
writeDigitalPin(a,’D13’,0);
pause(0.5);
end
clear a;

54
Ex3: Matlab plot + arduino
for i = 2:500
Plot the data from the analog
xval(i) = readVoltage(a,’A3’);
port using Matlab plot
xave(i) = (xval(i)+xval(i-1))/2;
subplot(2,1,1)
a=arduino(‘com3’,’uno’);
plot(xval, 'b');
title('x');
xval = zeros();
subplot(2,1,2)
xave = zeros();
plot(xave)
xval(1) = readVoltage(a,’A3’);
title('x average')
xave(1) = xval(1);
pause(.001)
pause(.001);
end
delete(a)

55
Arduino + Simulink

• Get Hardware Support Package


• Install from internet
• Select Arduino

56
Check Installation

57
Ex: LED in Simulink
1. Select Tools > Run on Target Hardware > Prepare to Run
2. When the Hardware Implementation pane opens, set
the Hardware board parameter to the specific Arduino board
3. Click the Deploy to Hardware button

58
Numerical Solution of ODE in Arduino

y[1]=5;

Euler 근사화 이용한 예 if (cnt==1){


void setup(){ for(i=1;i<50;i++){
Serial.begin(9600); Serial.println(y[i]);
} Serial.println(',');
void loop() { time = time+h;
int i = 1; y[i+1] = y[i]-h*sin(y[i])+h*time;
float y[50]; }
float h = 0.1; cnt=cnt+1;
float time=0; }
}
int cnt =1;
59
Numerical Solution of ODE in MCU
Matlab function dstate = ex1model(t,state)

dstate= -sin(state)+t ;
T=0:0.1:5;
state0=5;
[t,state]=ode45(@ex1model,T,state0);
figure(1)
plot(state)
hold on
out=load('output_data.txt')
plot(out,'r')
hold off

60
Solution
18
Matlab
Numerical method
16

14

12

10

4
0 10 20 30 40 50 60

61
Reference

• [1] http://arduino.cc/hu/Tutorial/HomePage
• [2] http://www.hardcopyworld.com/
• [3] 손에 잡히는 아두이노, 마사모 밴지, 인사이트
• [4] http://robobob.co.kr/
• [5] http://hardcopyworld.com

62
Appendix 1: 아두이노 메모리
• 스케치가 문제없이 업로드 되더라도 아래와 같은 작업을 한
뒤 문제가 발생한다면 메모리 문제일 가능성이 큼
– 하나 이상의 라이브러리를 include 한 뒤
– 몇 개의 LED pixel을 추가한 뒤 (LED 디스플레이의 각 픽셀을 말함)
– SD 카드에서 파일을 연 뒤
– 디스플레이를 초기화 한 뒤
– 다른 스케치와 합친 뒤
– 새로운 함수를 추가한 뒤

 아두이노의 메모리 구조에 대한 이해 필요함

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/1963
Appendix 1에서 메모리 문제를 소개하기 위하여 이 페이지의 내용을 요약하여 소개함

63
Appendix 1: 아두이노 메모리
• 프로세서/메모리 구조

폰 노이만(Von Neumann) 아키텍처 하버드 아키텍처


(컴파일 된) 프로그램과 (프로그램 (컴파일 된) 프로그램과
실행중 사용되는) 데이터 저장 공간을 (프로그램 실행중 사용되는)
위해 같은 메모리 공간을 사용 데이터 저장 공간을 위해 같은
메모리 공간을 사용
두 개의 상반된 아키텍처는 서로 장단점이 있음. 하버드 아키텍처가
성능에서 뛰어난 반면 폰 노이만 아키텍처는 더 유연함
http://www.hardcopyworld.com/ngine/aduino/index.php/archives/1963

64
Appendix 1: 아두이노 메모리
• 아두이노 UNO, Nano, Mini의 핵심 칩인 Atmega328 도
하버드 아키텍처를 사용
• 작성한 프로그램(스케치)은 플래시 메모리(32KB, 프로그램
메모리라고도 부름)에 저장되고 데이터는 SRAM(2KB)에 저
장됩
• 아두이노 같은 작은 장치에서는 한정된 메모리 자원을 아껴
써야 함.

아두이노
메모리
구조

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/1963

65
Appendix 1: 아두이노 메모리
아두이노 메모리
• 플래시 메모리(Flash Memory)
플래시 메모리는 프로그램 이미지와 초기화된 데이터가 저장되는 곳. 아두이노가 실행되면
플래시 메모리에서 프로그램 코드가 실행되지만 실행중인 코드에서 플래시 메모리를 바꿀
수는 없음. 플래시에 저장된 데이터를 바꾸기 위해서는 먼저 SRAM으로 복사를 해야함

• 램(SRAM, Static Random Access Memory)


– Static data: 전역 변수(global variable), static 변수용으로 예약된 공간
– Heap: 동적으로 할당되는 데이터들을 위한 영역
– Stack: 지역 변수(local variable)를 위한 공간
– Free memory: 위 3개의 영역으로 사용되지 않는 여유 공간

• EEPROM(1kB)
프로그램에서 읽고 쓸 수 있는 비휘발성 메모리

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/1963

66
Appendix 1: 아두이노 메모리
아두이노 메모리 측정
int freeRam ()
2 {
3 extern int __heap_start, *__brkval;
4 int v;
5 return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
6 }
힙과 스택 사이의 여유 공간 확인

• EEPROM
EEPROM은 100% 프로그래머가 제어가 가능함. 어디에 어떻게 쓰고, 언
제 어디서 어떻게 읽을지 스스로 계획해야 함. 따라서 별도로 사용량 측
정이 필요한 게 아니라 프로그래머가 알아서 관리해야 함

• 메모리 많이 소비하는 어플리케이션


– SD 카드, RGB Matrix Display, Monochrome OLED Displays
– ST7565 LCD Displays, e-Ink Displays,
http://www.hardcopyworld.com/ngine/aduino/index.php/archives/1963

67
Appendix 1: 아두이노 메모리
• 프로그램 바이너리 사이즈가 넘치는 경우 플래시 메모리를
확보해야 함
• Dead Code 없애기
– 사용되지 않는 라이브러리 : #include 로 포함된 라이브러리들, 주석
으로 제거해서 컴파일 해보고 문제 없으면 삭제해도 OK
– 사용되지 않는 함수 : 한 번도 호출되지 않는 함수들
– 사용되지 않는 변수 : 값은 종종 업데이트 되지만 실제 사용되지는
않는 변수들
– 실행되지 않는 코드 : 나중에 쓰일 것 같아 만들어둔 코드들, 에러를
대비해 디버깅 용도로 만들어 둔 코드들.
– 반복되는 코드 : 같은 코드가 소스코드 여러 곳에서 반복되는 경우
함수로 만들어서 호출하도록 처리
• 부트로더 제거
68
Appendix 1: 아두이노 메모리
램 문제 해결법
• 사용하지 않는 변수 제거
• F() 매크로 사용
• Reserve() 사용
• 읽기 전용 데이터에 PROGMEM 사용
• 버퍼 사이즈 축소
• 불필요하게 크게 잡은 변수 수정
• Global & Static Variables의 적절한 사용
• 동적 할당 (Dynamic Allocations)
• 지역 변수(Local Variables)

69
Appendix 2: 라이브러리 만들기
int pin = 13; void dash(){
void setup(){ digitalWrite(pin, HIGH);
pinMode(pin, OUTPUT); delay(1000);
} digitalWrite(pin, LOW);
void loop(){ delay(250);
dot(); dot(); dot(); }
dash(); dash(); dash();
dot(); dot(); dot(); 이 코드의 함수 dot 과 dash를 여러 곳에서 사용한다면
delay(3000); 이 함수들을 라이브러리로 만들어 두면 편리함.
} 라이브러리를 위해서는 다음 두 가지가 필요함
void dot(){ - 헤더파일(.h 확장자를 가진 파일)
digitalWrite(pin, HIGH); 함수와 변수의 정의와 선언

delay(250); - 소스파일(.cpp 확장자를 가진 파일)


실제 동작 코드
digitalWrite(pin, LOW);
delay(250);
}

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 2에서 라이브러리 제작을 소개하기 위하여 이 페이지의 내용을 요약하여 소개함

70
Appendix 2: 라이브러리 만들기
• 헤더 파일 (Morse.h) • 소스 파일 (Morse.cpp)
/* #include "Arduino.h"
Morse.h - Library for flashing Morse #include "Morse.h“
code. Morse::Morse(int pin){
Created by David A. Mellis, Nov. 2, 2007. pinMode(pin, OUTPUT);
Released into the public domain. */ _pin = pin;
#ifndef Morse_h }
#define Morse_h void Morse::dot(){
#include "Arduino.h" digitalWrite(_pin, HIGH);
class Morse delay(250);
{ digitalWrite(_pin, LOW);
public: delay(250);
Morse(int pin); }
void dot(); void Morse::dash(){
void dash(); digitalWrite(_pin, HIGH);
private: delay(1000);
int _pin; digitalWrite(_pin, LOW);
}; delay(250);
#endif }
71
Appendix 2: 라이브러리 만들기
• 라이브러리를 사용한 Morse 신호 생성 예제
#include <Morse.h>
Morse morse(13);
void setup()
{ }
void loop() {
morse.dot(); morse.dot(); morse.dot();
morse.dash(); morse.dash(); morse.dash();
morse.dot(); morse.dot(); morse.dot();
delay(3000);
}

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 2에서 라이브러리 제작을 소개하기 위하여 이 페이지의 내용을 요약하여 소개함

72
Appendix 3: 아두이노 두대 연결하기
• 구성: 아두이노 2대, 컴퓨터 한대
• 연결
컴퓨터 ----------- 아두이노MASTER --------------- 아두이노 SLAVE
USB ----------- Vcc --------------- Vcc
----------- GND --------------- GND
----------- 2번(TX) --------------- 0번(RX)
----------- 3번(RX) --------------- 1번(TX)

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 3에서 이 페이지의 내용을 요약하여 소개함

73
Appendix 3: 아두이노 두대 연결하기
• 아두이노 master (데이터수신) • 아두이노 slave (데이터송신)

#include <SoftwareSerial.h> void setup(){


int bluetoothTx = 2; Serial.begin(115200);
int bluetoothRx = 3; }
SoftwareSerial port(bluetoothTx, bluetoothRx);
void loop(){
void setup(){ Serial.print("h"); //h를 보냄
Serial.begin(115200); delay(500);
port.begin(115200); }
}

void loop(){
if(port.available()){
Serial.print((char)port.read());
}
}

74
Appendix 4: HXT900 마이크로 서보모터
• HXT900은 -90 ~ 90' 범위 약 180' 이내에서 위치를 제어하
는 마이크로 서보모터
– HXT900 9g / 1.6kg / .12sec Micro Servo
– Operating voltage : 3v ~ 6v
– Speed : 0.12 sec/60(4.8V)
– Torque : 2.5 kg-츠
– Temperature range : -30C~60C
– Plastic Bushing, 25cm wire
– Servo arms & screw included
– Gears: Nylon White type

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 4에서 이 페이지의 내용을 요약하여 소개함

75
Appendix 4: HXT900 마이크로 서보모터
• HXT900 제어를 위한 연결

서보모터 아두이노
GND (검정색 혹은 갈색) GND
PWR (적색) 5V
SIG (황색) Pin 2

• 펄스폭 1.5ms (= 1500us)를 입력하면 중심 위치에 맞춰지며 0.5ms 에서


-90', 2.5ms 에서 90' 회전한 위치에 맞춰짐
• 따라서 0.5 ~ 2.5ms 의 범위를 넘어가지 않도록 코드상에서 제어해줘야

• 서보모터는 각도 요청을 받기위해 20ms 주기로 펄스를 기다리므로 디지
털 핀에 신호를 주고 20ms 가 지나지 않았으면 다시 신호를 주지 않도
록 해야 함

76
Appendix 4: HXT900 마이크로 서보모터
int servoPin = 2; // control pin for servo motor void loop()
int minPulse = 600; // minimum servo position (0.6 ms) {
int maxPulse = 2400; // maximum servo position (2.4 ms) if (Serial.available() > 0)
int turnRate = 100; // servo turn rate increment {
// (larger value, faster rate) moveServo = Serial.read();
int refreshTime = 20; // time (ms) between pulses (50Hz)
// User contro: ASCII '<' == 60, ASCII '>' == 62
int centerServo; // center servo position if (moveServo == 60) { pulseWidth = pulseWidth ? turnRate; }
int pulseWidth; // servo pulse width if (moveServo == 62) { pulseWidth = pulseWidth + turnRate; }
int moveServo; // raw user input if (moveServo == 32) { pulseWidth = centerServo; }
long lastPulse = 0; // recorded time (ms) of the last pulse
// Check min, max
void setup() if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }
{ if (pulseWidth < minPulse) { pulseWidth = minPulse; }
pinMode(servoPin, OUTPUT); // Set servo pin as an output pin
centerServo = maxPulse ? ((maxPulse ? minPulse)/2); Serial.print("Pulse Width: ");
pulseWidth = centerServo; // Give the servo a starting point Serial.print(pulseWidth);
// (or it floats) Serial.println("us");
Serial.begin(9600); }
Serial.println(" Arduino Serial Servo Control");
Serial.println("Press < or > to move, spacebar to center"); // Send pulse only when update time(20 ms) has passed
Serial.println(); if (millis() ? lastPulse >= refreshTime)
} {
digitalWrite(servoPin, HIGH); // start the pulse
delayMicroseconds(pulseWidth); // pulse width
digitalWrite(servoPin, LOW); // stop the pulse
lastPulse = millis(); // save the time of the last pulse
}
}

77
Appendix 4: HXT900 마이크로 서보모터
• 서보 라이브러리를 사용한 예제
#include <Servo.h>
Servo servo;

int servoPin = 9;
int angle = 0; // servo position in degrees

void setup() {
servo.attach(servoPin);
}
void loop() {
// rotate from 0 to 180 degrees
for(angle = 0; angle < 180; angle++)
{
servo.write(angle);
delay(15);
}
}

78
Appendix 5: A4988 이용 스테핑 모터 구동
• 구동을 위한 회로 구성

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 5에서 이 페이지의 내용을 요약하여 소개함

79
Appendix 5: A4988 이용 스테핑 모터 구동
• 스텝 모터는 고유한 스텝 사이즈 크기를 가지고 있는데 (예. 1.8° 또는 1
회전 당 200 steps), 이 값이 full step 시 사용되는 값
• A4988 처럼 micro-stepping 을 지원하는 드라이버의 경우 1회전 당 200
step을 가진 모터를 1회전 당 400 혹은 800 스텝으로 컨트롤 할 수 있음
• STEP 핀으로 입력되는 하나의 펄스가 DIR 핀으로 설정된 방향으로 회전
하는 하나의 마이크로 스텝에 대응됨
• STEP 핀과 DIR 핀은 내부에 풀업, 풀다운 저항에 연결되지 않았으므로
floating 상태(비연결 상태)로 둬서는 안됨

80
Appendix 5: A4988 이용 스테핑 모터 구동
int stp = 13; //connect pin 13 to step else { //sweep 200 in dir 2
int dir = 12; // connect pin 12 to dir digitalWrite(dir, HIGH);
int a = 0; // gen counter a++;
void setup() { digitalWrite(stp, HIGH);
pinMode(stp, OUTPUT); delay(10);
pinMode(dir, OUTPUT); digitalWrite(stp, LOW);
} delay(10);
void loop() {
if (a < 200) { //sweep 200 step in dir 1 if (a>400) // Initialize
a++; {
digitalWrite(stp, HIGH); a = 0;
delay(10); digitalWrite(dir, LOW);
digitalWrite(stp, LOW); }
delay(10); } //simple A4988 connection
//jumper reset and sleep together
} } //connect VDD to Arduino 3.3v or 5v
//connect GND to Arduino GND (GND near VDD)
//connect 1A and 1B to stepper coil 1
//connect 2A and 2B to stepper coil 2
//connect VMOT to power source (9v battery + term)
//connect GRD to power source (9v battery - term)

81
Appendix 6: L298N을 이용한 DC 모터 구동
• L298N Dual H Bridge 모듈
– 드라이버 칩 : L298N 듀얼 H-브리지 드라이버 칩
– 드라이브 부분의 공급전압 VMS : +5 V ~ 35 V-
– 드라이브 부분의 최대전류 : 2A / bridge
– 로직 부분의 공급전압 VSS : 4.5-5 0.5 V
– 로직 부분의 작동 전류 범위 :0 ~ 36mA
– 입력제어신호 전압 범위 : H: 4.5~ 5.5V / L: 0V
– 최대 소비 전력 : 20W
– 보관 온도 : -25 ℃까지 130 ℃
– 드라이버 보드 크기 : 55mm * 60mm * 30mm
– 드라이버 보드 무게 : 33g
– 기타 기능 : 방향 제어 표시LED, 전원 표시 LED

http://www.hardcopyworld.com/ngine/aduino/index.php/archives/691
Appendix 6에서 이 페이지의 내용을 요약하여 소개함

82
Appendix 6: L298N을 이용한 DC 모터 구동
• 3개의 포트(파란색)를 아래와 같이 연결

아두이노 모터 드라이버 모듈 배터리


5V 5V
GND GND (-)
VMS (+)
• 모터의 회전 방향과 출력 제어를 위한 연결
• 모터 A 제어: ENA, IN1, IN2
• 모터 B 제어: ENB, IN3, IN4
• ENA, ENB는 아두이노의 PWM 지원되는 핀(D3, 5, 6, 9, 10, 11)에 연결하
고 나머지는 임의의 Digital 핀에 연결

83
Appendix 6: L298N을 이용한 DC 모터 구동
• ENA와 ENB는 모터 A, B를 Enable 시킬 것이냐를 결
정합니다. 아두이노에서 ENA, ENB에 High 전압을
걸어주고 IN1, IN2 입력을 조절해서 모터 방향을 제
어할 수 있음

ENA (or ENB) IN1 (or IN3) IN2 (or IN4) 모터 A (or B)
High High Low 정방향 회전
High Low High 역방향 회전
High High High 정지
High Low Low 정지
Low 상관없음 상관없음 정지

84
Appendix 6: L298N을 이용한 DC 모터 구동
void setup() { else if(direction == 2){ // Left
pinMode(2, OUTPUT); digitalWrite(2, LOW);
pinMode(4, OUTPUT); digitalWrite(4, HIGH);
pinMode(7, OUTPUT); analogWrite(5, speed);
pinMode(8, OUTPUT); } digitalWrite(7, HIGH);
void loop() { digitalWrite(8, LOW);
if(direction == 1){ // Forward analogWrite(9, speed); }
digitalWrite(2, HIGH); else if(direction == 3) { // Right
digitalWrite(4, LOW); digitalWrite(2, HIGH);
analogWrite(5, speed); digitalWrite(4, LOW);
digitalWrite(7, HIGH); analogWrite(5, speed);
digitalWrite(8, LOW); digitalWrite(7, LOW);
analogWrite(9, speed); } digitalWrite(8, HIGH);
else if(direction == 4){ // Backward analogWrite(9, speed); }
digitalWrite(2, LOW); else if(direction == 0){ // Stop
digitalWrite(4, HIGH); analogWrite(5, 0);
analogWrite(5, speed); analogWrite(9, 0);
digitalWrite(7, LOW); }
digitalWrite(8, HIGH);
analogWrite(9, speed); } }
IN1, IN2, ENA (D2, D4, D5), IN3, IN4, ENB (D7, D8, D9) 순서로 연결

85

Вам также может понравиться