I2C 통신

- CLOCK, DATA 회선 두 개로 통신하여 두 가닥(two-wire) 프로토콜이라고 불림

I2C 장치 : 대부분 MCU들이 외부 모듈과 통신할 수 있도록 표준화된 디지털 통신 프로토콜

I2C 버스 :

1. 최소한 입출력 핀으로 장치 간 양방향 통신 지원

2. 정보 보내는 마스터 1개, 정보 받는 슬레이브 장치 여러 개

 

7세그먼트 LED

공통 음극형 : 공통 핀을 GND에 연결, 각 세그먼트 핀에 HIGH(1) 신호를 걸면 LED 불이 켜진다.

 

잔상효과 : 한 번에 하나의 숫자를 표기하고 빠른 속도로 자리를 바꿔 표기하면 잔상효과에 의해 4자리가 동시에 표시

 

블루투스 : 통신 범위가 보통 수 미터~수십 미터 정도의 짧은 거리, 2.4GHz 대역인 ISM 대역 사용, 블루투스 5까지 나옴

 

인터럽트 : 시간 경과, 입력 상태 변화 등 특정 사건에 의해, 프로그램 코드가 비동기적으로 실행할 수 있게함

 

하드웨어 디바운싱 : RC회로를 만들면 스위치를 누를 때 저항과 콘덴서 값에 따라 결정되는 주기 동안 HIGH에서 LOW로 변하는 신호를 단 한 번만 생성해 준다.

 

반전 슈미트 트리거를 이용하여 하드웨어 디바운싱을 한 후 슈미트 트리거가 적용된 회로로 깨끗한 인터럽트 신호 만듦

 

인터럽트 내에서 값이 변경되는 변수는 반드시 volatile 형식으로 선언
attachInterrupt() 함수
아두이노가 프로그램 내에서 인터럽트를 사용하려면, setup() 함수에서 attachInterrupt() 함수로 인터럽트를 초기화
attachInterrupt(0, swap, RISING);
 
FND
d1~d4 : 자리수 (공통 음극 기준 출력하는 자리만 LOW)
A~H : 각 세그먼트 자리 (세그먼트는 예외적으로 키려면 HIGH, 끄려면 LOW)
 

I(2)C 통신

- 대부분 MCU 들이 외부 모듈과 통신할 수 있도록 표준화된 디지털 통신 프로토콜

- 버스는 최소한의 입출력 핀만 사용하여 장치 간 양방향 통신 제공

- 버스는 

1. 정보를 보내는 마스터(Master) 장치 1개

2. 정보를 받는 슬레이브(Slave) 장치 여러 개로 구성

- 보통 MCU가 마스터 역할하고 슬레이브들의 동작을 제어

- 통신은 느린 속도의 간단한 주변 장치와의 통신에 적합

- 통신의 최대 속도는 평균 수백(100~400)KHz로 낮은 속도에 해당

 

I(2)C 통신 역사

- 1980 초반 필립스에서 개발

- 1990 표준화 많은 회사에서 호환 칩 생상

- 통신은 CLOCK과 DATA 회선 두개로 통신하기 때문에 두 가닥(two-wire) 프로토콜이라고 불림.

- 통신이라는 이름을 사용하지 않더라도 두 개의 선에 의한 프로토콜을 사용하는 장치는 I(2)C 통신 표준 지원

 

I(2)C 장치 간 연결 방법

- 통신 시스템은 여러 장치가 동일한 통신 회선 공유

1. CLOCK신호(SCL) : 전송을 개시하는 클럭 펄스가 생성되는 회선 (pull-up 사용)

2. DATA 신호 (SDA) : 마스터와 슬레이브 장치 간 전송되는 양방향 데이터 회선 (pull-up 사용)

데이터 전송을 안할 때 -> float 현상 발생 -> 전압을 걸어 pull-up 저항을 건다.(1~10k옴 사이)

 

I(2)C 장치 간 통신 주소 설정

- 버스는 하나의 마스터 장치와 다수의 슬레이브 장치가 통신 회선 공유

- MCU인 아두이노가 마스터 장치 역할

- 마스터 장치만이 통신을 초기화 가능, 슬레이브 장치는 마스터 장치의 요청에 응답만 가능

- 각 주변 장치는 7비트 고유한 통신 주소를 갖음

-> 버스에 연결된 모든 장치가 동일한 메세지를 전달 받아 고유 주소가 중복되면 안된다.

- 마스터 장치는 통신 초기화 후, 장치 ID, 데이터 전송, 슬레이브 장치는 자신의 ID가 호출되면 요청 받은 데이터 전송

- 대부분 I(2)C는 사전에 프로그램된 다양한 I(2)C 주소가 지정

 

I(2)C 통신 절차 (protocol)

1. 마스터에서 시작 비트(Start)를 전송

2. 마스터에서 통신하려는 슬레이브 장치의 7비트 주소를 보낸다.

3. I(2)C장치에서 레지스터에 데이터를 쏠지 읽어올지에 따라, 마스터에서 쓰기명령(O)또는 읽기명렬(1)을 보낸다.

4. 슬레이브에서 acknowledge 또는 ACK(LOW신호)로 응답

5. 마스터는 I(2)C 장치의 레지스터를 읽어 오겠다는 1바이트 명령을 쓰기 모드로 전송하고,

슬레이브에서는 ACK 비트로 응답

6. 마스터는 I(2)C 기기에서 전송되는 1바이트 정보를 읽기 모드에서 수신.

1바이트를 읽고 나면 슬레이브에 ACK 비트 전송

7. 마스터에서 STOP비트를전송하여 마스터와  슬레이브 기기 간 통신 완료

- I(2)C 장치 사양에 따라 통신 절차가 조금씩 다르다.

- 아두이노에는 I(2)C 라이브러리 Wire가 내장되어 있어 어려운 타이밍 작업 처리

 

TC74 - 디지털 온도 센서(외부온도를 섭씨온도 값으로 전송(다른 아날로그 센서는 온도값을 0~1023로 변환해서 보냄)

다리 1 : NC - 사용 X

다리 2 : SDA - 데이터 (풀업) A4핀에 연결

다리 3 : GND

다리 4 : SCLK - 클럭 (풀업) A5핀에 연결

다리 5 : VCC - 전원

아두이노 A4,5에는 2가지 기능이 다중화 되어 있다.(하나를 쓰면 하나를 못씀)

1. 아두이노 I(2)C 인터페이스

2. 내장 ADC

 

I(2)C 온도센서 TC74센서에서 온도를 읽는 절차(Read Byte Format)

1. MCU는 TC74 주소를 전송하여 통신하고자 지정

2. MCU는 쓰기 모드에서 명령값 0(Read Temperature Register:RTR)을 전송

3. MCU는 TC74 주소를 다시 전송 TC74가 읽을 대상임을 다시 알려줌

4. MCU는 기다렸다 TC74가 보낸 8비트 온도 데이터를 읽음

 

I(2)C 라이브러리 삽입

#include <Wire.h>

 

I(2)센서 ID를 10진수로 저장한 변수 선언

int temp_address=72; // A0 : 1001000 = 72

 

setup()에 Wire.begin() 사용 (I(2)C Wire 객체 시작)

 

loop()에

1. Wire.beginTransmission(temp_addreess); // I(2)C 센서의 주소와 통신을 개시하는 요청 전송

2. Wire.write(0); // 온도 레지스터를 읽겠다는 명령(0)을 쓰기모드에서 전송

3. Wire.endTransmission(); // 전송 완료(0값 전송 종료)

4. Wire.requestFrom(temp_address,1); // 지정 주소 I(2)센서(온도 센서)에서 읽기 모드로 1바이트 온도값 읽음

5. while(Wire.available()==0); // 응답이 올 때까지 대기

6. int c = Wire.read(); // 온도 레지스터 값을 읽어와 변수에 저장

- int f=round(c*9.0/5.0 +32.0); // 섭씨->화씨 변환

7 세그먼트 LED
- 일반 명칭 FND (Flexible Numeric Display)

- 7개 선분으로 숫자 표시, 실제는 소숫점을 표시하는 LED 추가하여 8개

-> 1개 바이트로 제어 가능

- 종류 : 공통 양극, 공통 음극

-> 핀 개수, 위치 동일

-> 핀 번호는 소수점 있는 면이 가장 왼쪽 1번, 반시계로 증가

 

7 세그먼트 LED : CLS-5612BUR-11

- 공통 핀을 Vcc에 연결, 각 세그먼트 핀에 LOW(0) 신호를 걸면 LED 불이 켜진다.

- 공통 음극형 5611AS(Common Cathode)는 반대다.

-> 공통 핀을 GND 연결, 각 세그먼트 핀에 HIGH(1) 신호 걸면 LED 불이 켜짐

- 세그먼트 핀은 a->b->c->d->e->f->g->dp(h) 순서로 표시 (시계방향)

 

7세그먼트 LED는 A~H까지 연결된 아두이노 핀 번호를 알아야함

-> A부터 H까지 3, 2, A4, A3, A2, 4, 5, A5 순서

7 Segment LED의 A부터 연결된 아두이노 핀번호 순서대로 등록

digits[] []에서 0~9까지 표현할 수 있는 조합 설정

공통 전원선인 3,8번 핀은 하나만 연결해도 된다.

 

setSegments(i); //위에 나온 숫자를 7세그먼트 LED로 표현

->void setSegments(int n){ for(inti=0;i<8;i++){digitalWrite(segmentPins[i], digits[n][i]);}}

 

4자리 7세그먼트 표시장치를 위해서는 32개 제어선 소요->너무 많이 소요되어 좋은 방법 아님

-> 사람 눈의 잔상효과를 이용

-> 한 번에 하나의 숫자를 표시하고 빠른 속도로 바꾸어 표시 반복 -> 잔상으로 인해 4자리가 동시에 표시되는 효과

=> 32핀이 아닌 12핀으로 동작 가능 (8개 핀은 7세그먼트의 8개 핀과 동일, 4개는 자릿수 선택) 

 

FND 배열 부품 연결

- 아두이노 10,11,12,13핀으로 네 자리 출력을 원하는 자릿 위치 선택

-> byte digitPins[] = {13,12,11,10}; //d1,d2,d3,d4

- 8개 세그먼트 제어하는 핀은 각 자리마다 공통으로 연결

-> byte segmentPins[] = {2,3,4,5,6,7,8,9}; //A,B,C,D,E,F,G,H

- 공통 음극 방식이면

-> d1(10핀)에 LOW를 걸어 출력 선택

 

LCD 핀

1.GND

2.Vcc

3.RS - LCD 용도 결정, 명령 실행 시키는 커맨드 모드, 문자 출력하는 문자 모드 중 선택 (2핀)

4.EN - 전송할 데이터 준비 여부 LCD에 알려주는데 사용 (3핀)

5.RW - 읽기/쓰기 모드 (쓰기 모드 사용->항상 GND와 연결)

6.D4,D5,D6,D7 -D0~D3은 4핀 모드라 사용 안함 (4,5,6,7핀)

 

LCD에 텍스트 표기

#include <LiquidCrystal.h> //라이브러리

LiquidCrystal lcd(2,3,4,5,6,7); //LCD객체 초기화

lcd.begin(16,2); //16x2 LCD 문자열 크기 지정

lcd.setCursor(0,1); //커서 이동 함수: 0열 1행

lcd.print("Cho's Display"); //문자 출력 함수

 

bitRead(x,n);

x : 데이터

n : 읽어낼 비트 위치(LSB부터 0에서 시작)

반환값 0 or 1 비트값

 

아두이노 I2C LCD 문자열 출력

1. GND - GND

2. VCC - 5V

3. SDA - A4

4. SCL - A5

 

블루투스 통신

- 대표적 유선 통신 방식식인 RS-232C를 무선으로 대체

- 통신 범위가 보통 수 미터~수십 미터 정도 짧은 거리

- 2.4GHz 대역 ISM 대역 사용

- 현재 블루투스 5까지 소개

 

블루투스 통신이란

- 기기간 통신을 정의하기 위해 프로파일 사용

-> SSP(Serial Port Profile)사용

-> 시리얼 통신을 에뮬레이션하는 프로파일

-> 유선의 UART가 무선의 블루투스 통신으로 바뀐 점만 다름

- 시리얼 유선 통신용 코드를 무선 통신으로 쉽게 바꿀 수 있다.

 

블루투스를 사용하기 위해서 식별 가능한 블루투스 이름 부여

-> 이름 바꿀 때 ATcommand 사용

-> ATcommand 명령 집합은 BLE 모듈의 데이터 시트 참조

=> 시리얼 모니터 입력창에 "AT+NAME바꿀이름" 을 입력

=> 명령어가 제대로 반영하기 위해 AT+RESET명령어로 초기화 시켜준다.

=> 제대로 반영됐다면 reset success가 출력

- 변경된 이름 확인 AT?NAME 명령어 (현재 블루투스 모듈 이름 출력)

 

블루투스 모듈에 관한 기본 정보 -> ATcommand사용

1. 블루투스 모듈의 이름 <- 이름만 설정 나머지는 default값 사용

2. 블루투스 통신 속도 - default : 9600 baud rate

3. 4자리 핀 번호 - default : N, 8, 1.

4. 슬레이브/마스터 모드 - default : Slave

 

갈검갈금 100옴 저항

갈검주금 10k옴 저항

빨빨갈금 220옴 저항

갈녹갈금 150옴 저항

 

74HC14 : inverter = Low를 High로 High를 Low로

 

인터럽트 : 가로채기 interrupt (특정 사건에 의해 프로그램 코드가 비동기적으로 실행가능)

- cpu가 프로그램 실행 중 입출력 하드웨어 등의 장치 또는 예외 상황이 발생해 긴급한 처리가 필요할 때 cpu에게 처리하라고 알리는 기능.

 

하드웨어 인터럽트

입력 I/O핀의 상태에 변화가 있을 때 사용

-> 프로그램 내 끊임없이 특정 버튼 상태 감시하지 않으면서도(polling,폴링) 상태 변화가 발생했을 때 값 변경 유용

 

폴링(polling)은 loop문 내에서 반복적으로 외부 입력을 감시하는 방식

소프트웨어 구현 용이성은 폴링이 간편하며, 하드웨어 구현은 똑같다.

-> 에지 트리거를 사용하려면 하드웨어 디바운싱이 미리 구현되야한다.

 

에지 트리거

High->Low : falling edge

Low->High : rising edge

 

인터럽트 적용 영역

- 멀티 태스킹 : 하드웨어 인터럽트를 사용하는 가장 큰 이유

- 수신 정확도 : 빠른 수신이 필요한 작업에 인터럽트가 절대적

 

아두이노는 인터럽트 사용할 수 있는 I/O핀이 지정되어있다.

 

인터럽트ID는 attachInterrupt()와 함께 사용

하드웨어 인터럽트는 인터럽트 핀을 특정 함수에 붙여 사용해야 동작

-> 마지막으로 인터럽트는 언제 적용할 시점에 대해서는 신호 작동 위치를 인수로 사용

ex) attachInterrupt(BUTTON_INT,swap,RISING);

-> 하드웨어 인터럽트 I/O인 BUTTON_INT 상태가 RISING EDGE로 변할 때 swap()호출

 

스위치 바운싱 효과로 노이즈 발생 -> 인터럽트 2번 발생 가능 (디바운싱 처리 하기)

=> RC회로로 처리 resistor condenser회로 (곡선화된 신호 만듦 : 상태가 천천히 바뀜)

- 하드웨어 디바운싱 처리 : 반전(inverting)슈미트 트리거 74HC14를 사용

-> 특정 임계치 초과하면 급변하는 에지를 생성함.

-> 슈미트 트리거를 사용하여 부드럽게 떨어지는 에지를 날카롭게 만들어 줌

 

콘덴서 회색 줄부분 음극(-)

 

volatile 변수

- 인터럽트 내에서 값이 변경되는 변수는 반드시 volatile 형식으로 선언

ex) volatile int selectedLED=9;

 

attachInterrupt() 함수

- 아두이노 프로그램 내에서 인터럽트 사용하려면 setup()함수에서 attachInterrupt()함수로 인터럽트 초기화

ex) attachInterrupt(0,swap,RISING);

- 0 : 인터럽트 0번(Uno 기준 2번 핀)

- swap : 인터럽트 호출 시 실행될 함수 이름

- RISING/FALLING : 인터럽트 언제 호출할 지 에지 시점 설정

 

아두이노 내장 타이머 3개

- millis()함수, delay()함수, analogWrite()함수로 PWM 출력을 위해 모든 내장 타이머 사용중

 

타이머 인터럽트

- 아두이노 내장 타이머는 아두이노 구동하는 수정 발진자의 클록 사이클마다 0부터 숫자를 센다.

- TimerOne은 16비트 타이머로 0~2^16-1까지 숫자를 셀 수 있다.

- 숫자가 최대가 되면 다시 0으로 초기화되며, 다시 숫제를 센ㄷ.

- 숫자가 최대값에 도달하는 시간은 클록 디바이더에 따라 다르다.

-> 클록 디바이더 사용 안하면 아두이노 클록 속도는 초당 16MHz(2^24)이기에 1초 동안 타이머가 여러 번 초기화됨

 

TimerOne 소프트웨어 타이머

- 9,10 I/O 핀 사용

 

<TimerOne.h>

Timer1.initialize(1000000); // 타이머를 1초로 설정

Timer1.attachInterrupt(blinky); // 타이머 인터럽트 발생 시 blinky()호출 

'학교수업' 카테고리의 다른 글

사물인터넷의 이해 11주차  (0) 2021.12.17
사물인터넷의 이해 10주차  (0) 2021.12.16
객체지향 프로그래밍 13주차  (0) 2021.12.10
정보보호개론 14주차  (0) 2021.12.10
가상현실프로그래밍 14주차  (0) 2021.12.09

+ Recent posts