https://markspeople.tistory.com/92

 

[어셈블러 입문] 레지스터와 스택

  이번글에서는 레지스터의 종류와 스택에 대해서 알아보도록 하겠습니다. 레지스터는 CPU내부의 대표적인 저장장치입니다. 레지스터는 CPU의 설계에 따라,또는 사용하는 용도와 목적에 따라 종

markspeople.tistory.com

굿

펌웨어를 하기 위해서 필요로 하는게
1. 전자 소자들 이해 
 - RLC, 각종 IC, falling edge, rising edge 등 클럭에 대한 이해
2. 프로그램 작성 능력
 - 그냥 프로그램 작성은 잘하시니 괜찮은데 이게 하드웨어 전용 프로그램이 되면 골치가 아픕니다. OJ님이 올린걸 보니 생체 신호 관련해서 하는건데 저걸 하려면 제어기법들은 기본으로 해서 보통 석박사들을 많이 써요. 대학 4년배워도 저건 좀 많이 빡십니다.
3. 회로도 해석 및 작성 능력
 - 펌웨어 한다고 하면 기본적으로 PCB기판 해석 및 설계를 할 줄 알아야 해요 패턴 굴기 길이 같은거에 타이밍도 달라져서.....
4. MCU 이해
 - 타이머(PWM 포함), 카운터, GPIO, 외부인터럽트, ADC, Serial 통신(TTL, 232, 485, SPI, I2C등등), 무선통신 (Zigbee, bluetooth 등) 보통 여기서 많이 포기하십니다. 딱 요렇게만 알아둬도 일을 할 수 있지만 대게 저걸 보자마자 포기하더라고요...
5. 범용장비가 아닌 전용장비
 - 칩이 달라지면 설정이 완전히 달라지는 경우도 존재합니다......... 요놈때문에 요즘 PC 소프트웨어쪽으로 인력이 치중된거 같아요

 

아는 분이 작성해주신것 이다. 나중에 공부해보자

https://www.draw.io

 

Flowchart Maker & Online Diagram Software

Flowchart Maker and Online Diagram Software diagrams.net (formerly draw.io) is free online diagram software. You can use it as a flowchart maker, network diagram software, to create UML online, as an ER diagram tool, to design database schema, to build BPM

app.diagrams.net

 

RS-232C ,RS-422, RS485 : 통신규약

RS-232C는 핀번호까지 정해져있다. (GND가 있다.)

RS-422,RS-485 의 전압레벨은 같다. 다른점은 신호를 보내면서 받을 수 있냐 없냐 차이다.

 

RS485 : 멀리 있는 곳에 보낼 수 있다.

D-SUB : 커넥터 타입

 

 

 

내용은 구글 번역기를 돌려서 작성함.

1、제품 개요
DHT11 디지털 온도 및 습도 센서는 보정된 센서가 포함된 복합 센서입니다.
온도와 습도의 디지털 신호 출력. 전용 디지털 모듈 적용
수집 기술 및 온도 및 습도 감지 기술,
제품은 높은 신뢰성과 우수한 장기 안정성을 가지고 있습니다. 센서에는 저항성 감각이 포함됩니다.
젖은 구성 요소 및 NTC 온도 측정 장치의 연결
고성능 8비트 마이크로컨트롤러.

2、응용 프로그램
HVAC, 제습기, 시험 및 검사 장비, 소비재, 자동차, 자동
제어, 데이터 로거, 기상 관측소, 가전 제품, 습도 조절기, 의료 및 기타 습도
측정 및 제어.
3、특징
저렴한 비용, 장기 안정성, 상대 습도 및 온도 측정, 우수한 품질, 빠른
응답, 강력한 간섭 방지 기능, 장거리 신호 전송, 디지털 신호 출력 및
정확한 교정.
4, 치수(단위: mm)

5, 제품 매개변수
 
상대 습도
해상도: 16비트
반복성: ±1% RH
정확도: 25℃ ±5% RH에서
호환성: 완전히 교환 가능
응답 시간: 25℃ 6초의 1 / e(63%)
1m/s 공기 6s
히스테리시스: <± 0.3% RH
장기 안정성: <± 0.5% RH / 년
온도
해상도: 16비트
반복성: ±0.2℃
범위: 25℃ ±2℃에서
응답 시간: 1/e(63%) 10S
전기적 특성
전원 공급 장치: DC 3.5~5.5V
공급 전류: 측정 0.3mA 대기 60μ A
샘플링 주기: 2초 이상
핀 설명
1, VDD 전원 공급 장치 3.5~5.5V DC
2개의 DATA 직렬 데이터, 단일 버스
3, NC, 빈 핀
4, GND 접지, 음의 전원

6, 일반 회로

마이크로프로세서와 DHT11의 연결은 위와 같은 전형적인 응용회로, DATA pull
마이크로프로세서 I/O 포트가 연결됩니다.
1. 5.1K에서 20m의 짧은 케이블 길이에 권장되는 일반적인 응용 회로
풀업 저항, 아래쪽에 있는 풀업 저항 아래 20미터 이상의 저항
실제 상황.
2. 3.5V 전압 공급 케이블을 사용할 때 케이블 길이는 20cm를 넘지 않아야 합니다. 그렇지 않으면 라인
전압 강하로 인해 측정 오류로 인해 센서 전원 공급 부족이 발생합니다.
3. 각각의 온도 및 습도 값은 마지막 측정 결과입니다.
실시간 데이터, 순차 읽기 2회, 센서를 반복적으로 읽는 것은 권장하지 않습니다.
읽기 센서 간격이 5초보다 크면 정확한 데이터를 얻을 수 있습니다.

7, 직렬 통신 명령(단선 양방향)
◎편도 버스 설명
DHT11은 단순화된 단일 버스 통신을 사용합니다. 하나의 데이터 라인만 있는 단일 버스, 시스템
데이터 교환, 단일 버스에 의한 제어가 완료됩니다. 오픈 드레인을 통한 장치(마스터 또는 슬레이브)
또는 장치가 버스를 해제하기 위해 데이터를 보내지 않도록 데이터 라인에 연결된 3상 포트,
다른 장치가 버스를 사용하는 동안; 단일 버스에는 일반적으로 약 5.1kΩ 풀업 저항이 필요한 외부 버스가 필요합니다.
따라서 버스가 유휴 상태일 때 상태가 높음입니다. 마스터-슬레이브 구조이기 때문에
호스트가 슬레이브를 호출하면 슬레이브가 응답할 수 있으며 호스트 액세스 장치는 엄격하게 따라야 합니다.
단일 버스 시퀀스, 혼돈 시퀀스인 경우 장치는 호스트에 응답하지 않습니다.
◎정의된 데이터 전송을 위한 단일 버스
DATA 마이크로프로세서와 DHT11 간의 통신 및 동기화용, 단일 버스
데이터 형식, 40개 데이터 전송, 높은 우선 순위.

데이터 형식:
8비트 습도 정수 데이터 + 8비트 습도 10진수 데이터 + 8비트 온도 정수 데이터 +
8비트 분수 온도 데이터 +8비트 패리티 비트.
◎패리티 비트 데이터 정의
“8bit 습도 정수 데이터 + 8bit 습도 정수 데이터 + 8bit 온도 정수 데이터 + 8bit
온도 분수 데이터" 8비트 체크섬은 마지막 8개의 결과와 같습니다.
예 1: 40개의 데이터가 수신됨:
0011 0101 0000 0000 0001 1000 0000 0000 0100 1101
높은 습도 8 낮은 습도 8 높은 온도. 8 저온 8 패리티 비트
계산하다:
0011 0101+0000 0000+0001 1000+0000 0000= 0100 1101
수신된 데이터가 정확합니다:
습도: 0011 0101=35H=53%RH
온도:0001 1000=18H=24℃
예 2: 40개의 데이터가 수신됨:
0011 0101 0000 0000 0001 1000 0000 0000 0100 1001
높은 습도 8 낮은 습도 8 높은 온도. 8 저온 8 패리티 비트
계산하다:
0011 0101+0000 0000+0001 1000+0000 0000= 0100 1101
01001101≠0100 1001
수신된 데이터가 올바르지 않습니다. 데이터를 다시 수신하는 것을 포기하십시오.

◎데이터 타이밍도
신호를 보내는 사용자 호스트(MCU), 저전력 모드에서 고속 모드로 변환된 DHT11,
호스트가 DHT11의 끝을 알리기 시작할 때까지 40비트 데이터를 보내기 위해 응답 신호를 보내고,
편지 수집을 시작합니다. 신호는 그림과 같이 전송됩니다.

참고: 호스트는 항상 마지막으로 측정된 DHT11의 온도 및 습도 데이터를 읽습니다.
측정된 시간 간격의 두 배와 같은 값은 매우 길며, 두 번째 연속 읽기
실시간 온도 및 습도 값의 값.

 

1 단계:
DHT11 전원을 켠 후(DHT11 전원을 켠 후 이 기간 동안 불안정한 상태에서 1S 동안 대기
어떤 지시를 보낼 수 없습니다), 테스트 환경 온도 및 습도 데이터를 기록하고 데이터를 기록합니다.
DHT11이 풀업 저항에 의해 당겨지는 DATA 데이터 라인이 높게 유지되는 동안; DHT11
DATA 핀은 입력 상태로 외부 신호를 감지하는 순간입니다.
2 단계:
마이크로프로세서 I/O는 동시에 출력을 낮게 설정하고 낮은 유지 시간은 더 적을 수 없습니다.
18ms보다 빠르면 풀업 저항으로 인해 마이크로프로세서 I/O가 입력 상태로 설정됩니다.
마이크로프로세서/O DHT11 데이터 데이터 라인도 하이, DHT11이 신호에 응답하기를 기다리고, 전송
표시된 신호:

 

3단계:
DATA 핀은 DHT11 로우의 외부 신호를 감지하고 외부 신호 로우 엔드를 기다립니다.
출력 상태에서 DHT11 DATA 핀을 지연, 응답 신호로 80 마이크로초의 낮은 출력,
80마이크로초의 높은 알림 주변 장치가 데이터를 수신할 준비가 된 후 출력됩니다.
이 때 마이크로프로세서 I/O는 입력 상태에서 I/O low(DHT11 응답 신호)가 감지되면 대기
80마이크로초의 하이데이터 수신 및 송신 신호:

4단계:
DHT11에 의해 DATA 핀 40에 의해 출력, 마이크로프로세서는 데이터 "0" 형식의 40 데이터 비트를 수신합니다.
I/O 레벨의 변화에 따라 50마이크로초 및 26-28마이크로초의 낮은 수준,
비트 데이터 "1" 형식: 낮은 플러스의 높은 수준, 50마이크로초 ~ 70마이크로초. 비트 데이터 "0", "1" 신호

종료 신호:
DHT11 DATA 핀이 40개의 데이터를 출력한 후 낮은 50마이크로초를 계속 출력하고,
풀업 저항이 높아지면서 입력 상태가 변경되었습니다. 그러나 DHT11 내부 재시험 환경
온도 및 습도 데이터, 데이터 기록, 외부 신호 도착 대기

8. 정보의 적용
1. 작업 및 보관 조건
센서 외부에서 제안된 작업 범위는 최대 300%RH까지 신호의 일시적인 드리프트를 유발할 수 있습니다. 로 돌아가
정상 작동 조건에서 센서 보정 상태는 천천히 회복됩니다. 복구 프로세스의 속도를 높이려면
"처리 재개"를 참조할 수 있습니다. 비정상 작동 조건을 장기간 사용하면 노화가 가속화됩니다.
제품.
구성 요소를 장기간 결로 및 건조한 환경 및 다음과 같은 장소에 두지 마십시오.
환경.
 A, 소금 스프레이
 B, 이산화황, 염산과 같은 산성 또는 산화성 가스
권장 보관 환경
 온도: 10 ~ 40 ℃ 습도: 60% RH 이하
2. 화학물질 노출의 영향
정전식 습도 센서는 화학 증기 간섭, 화학 물질의 확산에 의해 층을 가지고 있습니다.
감지 층은 측정값의 드리프트 및 감소된 감도로 이어질 수 있습니다. 깨끗한 환경에서 오염물질
천천히 출시됩니다. 아래에 설명된 대로 처리를 재개하면 이 프로세스가 가속화됩니다. 의 높은 농도
화학적 오염(예: 에탄올)은 센서의 민감한 층을 완전히 손상시킵니다.
3. 온도 영향
가스의 상대 습도는 온도에 크게 의존합니다. 따라서 습도 측정에 있어서,
습도 센서가 동일한 온도에서 작동하는지 확인해야 합니다. 열 방출과 함께
전자 부품은 인쇄 회로 기판을 공유하므로 설치는 센서에서 가능한 한 멀리 떨어져 있어야 합니다.
인클로저의 통풍을 잘 유지하면서 전자 부품을 열원 아래에 장착합니다.
열전도율 센서와 인쇄회로기판을 줄이기 위해서는 동도금을 가능한 한 최소화해야 하며,
그리고 둘 사이에 틈을 둡니다.
4. 가벼운 충격
햇빛이나 강한 자외선에 장기간 노출되면 성능이 저하됩니다.

여기까지가 구글 번역기로 돌린 내용입니다.

이제 프로그래밍적으로 해석을 한번 해보도록 합시다.

https://github.com/stan60805/studata/find/master

 

GitHub - stan60805/studata: test

test. Contribute to stan60805/studata development by creating an account on GitHub.

github.com

깃허브에 친절하게 짜인 코딩이 있습니다. 

Visual Studio로 코드를 옮겨서 해석해 봅시다.(참고로 Visual Studio 2019로 작업함)

C++ 빈프로젝트로 하나 만듬

클래스 하나 만듬

추가해주고요

1. #if defined(ARDUINO) && (ARDUINO >= 100)은 전처리기로써 아두이노에서 그리고 아두이노 1.00버전 이상에서 실행 시키겠다는 건데, 그 내용이 #include<Arduino.h>의 파일을 아두이노에서 실행시키겠다는 말이다.

 

2. #define DHTLIB_OK 0

   #define DHTLIB_ERROR_CHECKSUM -1

   #define DHTLIB_ERROR_TIMEOUT -2

   미리 함수에서 리턴을 시켜줄 값들을 전처리기에서 미리 선언해주는 것이다.

 

3. 클래스 내용들이다.

   int read(pin) -> 아두이노에서 read를 써서 pin번호를 받는 함수를 하나 만드는것이다.

   int humidity -> 아두이노에서 습도를 받아올 변수이다.

   int temperature -> 아두이노에서 온도를 받아올 변수이다.

 

※ 빨간줄은 visual studio ide에선 추가해준 헤더가 없기 때문에 뜨는 것이니 신경 안써도된다. 어차피 아두이노로 옮겨지면 거기서 쓰이는 함수들이나 데이터 타입이기 때문에 아두이노에서 컴파일을 하면 동작이 실행된다.

우선 봐야 될것은 위의 메뉴얼에 7, 직렬 통신 명령(단선 양방향) 란에 설명이 나와있을것이다.

거기서 밑에 보면 아래와 같은 설명이 나와있다.

데이터 형식:
8비트 습도 정수 데이터 + 8비트 습도 10진수 데이터 + 8비트 온도 정수 데이터 +
8비트 분수 온도 데이터 +8비트 패리티 비트.

DHT센서에서 데이터를 주면, 읽어들이는 형식은 8비트 X  5개 = 40비트를 읽어서 해석을 하면 된다.

거기에 대한 정보가 위와 같다. 그러므로 위의 코드를 아래에 설명을 하겠다.

1. uint8_t bits[5] -> 8비트의 데이터 타입을 가진 bit변수를 5개 만드는 것이다. 고로 40비트를 담을수 있는 변수를 만드는것이다.

 uint8_t cnt -> 8비트 0000 0000 의 각 비트 자리수를 시프트 연산을 하기 위한 변수로 활용된다.

 uint8_t idx -> bit[5]개의 인덱스 즉 [ ]칸에 숫자를 바꿔주기 위한 변수이다.

2. for(int i = 0; i < 5; i++) bits[i] =0 -> bits안에 있는 값들을 0으로 초기화 하는것이다. 의미는 초기화해서 쓰면 보기 편하기 때문이다.

3. 위에 메뉴얼에 보면 ◎데이터 타이밍도 라는 란이있다. 밑에 단계별로 적혀져있는데 1단계에 Low신호를 주고 18ms만큼 기다리는 부분이 있고, 2단계에서 신호를 입력 받을 준비를 하는 부분이있다.

코딩에서보면 단계별 진행이 이루어 진다.

 ① pinMode(pin , OUTPUT) 으로 설정(PIN에 신호를 출력을 하겠다고 설정하는것)

 ② Digitalwrite(pin , LOW) 에서 LOW 즉, 0인 신호를 보냄.

 ③ Delay(18) -> 18ms지연을 함.

 ④ Digitalwrite(pin, HIGH)에서 HIGH 즉, 1인 신호를 줘서 입력을 받을 준비를 함.

 ⑤ DelayMicroseconds(40)은 전기적 신호가 LOW -> HIGH로 파형으로 올라가기 때문에 시간이 있기 때문에 40us로 대기시간을 줌. 왜냐하면 위의 데이터 시트상에서 보면 HIGH가 되어야 입력을 받을 준비가 되기 때문에 정확하게 하려고 하기 때문이라고 봄. (40us는 임의로 준것으로 보임)

 

4. 위에서 2단계 진행 후 3단계가 있는데, 아래의 그림과 같이 LOW신호를 80us로 신호를 읽고 , 그뒤 HIGH 신호를 80us만큼 신호를 읽는다.(참고로 Host signal은 쓰는 것이고 Slave signal은 읽어 들이는것이라고 보면 되겠다.)

 ① unsigned int loopCnt = 10000 -> while문을 무한루프 돌렸을 때 필요한 카운터

(왜 10000을 설정했냐면 루프가 while1초에 1000번인가? 몇번인지는 잘 모르겠는데 엄청 돌아갈 것이다. 그만큼 시간에 횟수를 넉넉히 잡아 LOW 신호를 받을때까지 돌리겠다는 거다. 위의 80us보다는 많을 것이니 그거 염두하고 설정한듯 하다.)
 ② while (digitalRead(pin) == LOW) -> 핀번호를 넣고 읽어 들였을 때 LOW신호가 아닐때까지 무한       루프 돌린다. 
 ③ if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT -> while문이 한번 돌때마다 loopCnt를 1식 감소시켜 0이 되면 함수를 리턴시켜 LOW신호가 안들어 왔음을 알린다.

5. LOW신호가 끝나면 뒤에 HIGH신호가 들어오게 되는데 HIGH신호가 아닐때까지 무한루프 돌린다.

 ① loopCnt = 10000;
 ② while (digitalRead(pin) == HIGH)
 ③ if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

 

 

1. 위와 같이 40비트 데이터를 받아오기 위해 for문을 40번 돌린다.

2. 이것도 위에서 본 내용과 동일하다. 단지 데이터 시트가 조금 다른데 아래의 그림을 보고 코딩을 보도록하자.

아래의 코딩을 위에서 설명한것과 똑같다. 대신 처음 LOW신호는 50us이고 뒤에 HIGH신호는 0의 신호로 보는 시간은 26us~28us 이고 1인 신호로 보는 시간은 70us이다. 이걸 이해하고 코딩을 보도록하자.

loopCnt = 10000  
while (digitalRead(pin) == LOW) ----------------------------> LOW신호를 아닐때까지 while문 돌리는문장.
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

 

unsigned long t = micros();

loopCnt = 10000;
while (digitalRead(pin) == HIGH)   ------------------------> HIGH신호를 아닐때까지 while문 돌리는 문장
if (loopCnt-- == 0) return DHTLIB_ERROR_TIMEOUT;

3. 중간에 특이한것이 있다. unsigned long t = micros() 인데 LOW가 끝나는 시점에서 ms초 시간을 한번 재고 HIGH신호가 아닐때까지 시간을 재서 얼마나 지났는지를 확인하기 위한 용도로 쓰인다.

4. if ((micros() - t) > 40) bits[idx] |= (1 << cnt)가 있는데 풀어서 써보겠다.

    ① if ((micros() - t) > 40) -> 아까 위에서 봤듯이 현재 시간이 얼마나 지낫는지를 확인하기 위한 용도로 쓰인다. 현재 지난 시간이 40ms이상이면 신호가 1로 판단하고 , 그 이하면 0으로 판단한다.

    ② bits[idx]  = bits[idx] | (1 << cnt) -> bits안의 비트와 1 << cnt(위에서 7로 설정) OR연산을 하여 8번째에 비트를 넣겠다는 것이다. 

0000 0000 | 1000 0000 을 연산하면 -> 1000 0000의 값이 bits[idx]에 저장이 된다는 것이다. 즉 신호가 들어올때마다 비트를 이동시켜 신호를 저장하겠다는 말이다.

5. if (cnt == 0)   
   {
      cnt = 7;    
      idx++;      
   }
   else cnt--;

cnt가 0이면 cnt를 7로 바꾸고 idx를 1식 증가시킨다는것이다. cnt가 0이 아니면 1식 감소시킨다. 이말인 즉,

화살표 방향대로 신호를 저장하겠다는 거고 cnt 즉 8비트가 다 차면 그 옆 8비트로 이동시켜 신호를 저장하겠다는 뜻이다.

 

마지막 부분이다.

1. bits[0]은 습도로 저장을 한다. bits[2]는 온도로 저장을 한다.

2. 체크썸이라고 하는 부분이다. 체크썸은 데이터를 주고 받을 때 정확히 보낸 데이터와 받는 데이터가 맞는지 확인하는 용도로 쓰인다. 여기에선 bits[1] , bits[3]은 항상 0이기 때문에 체크썸에 포함 안시키고 bits[0] + bits[2] 만 체크썸을 한다.

3. bits[4] 읽은 체크섬과 읽은 sum의 값이 아니면 체크썸 에러를 띄우게 되어있다.

이제 아두이노에 적용해보자.

CPP파일과 h파일을 압축한다.

아두이노를 열고 스케치-> 라이브러리 포함하기 -> .ZIP라이브러리 추가를 통해 아까 ZIP파일 만든걸 찾아 넣으면 된다.

아두이노 소스 파일은 아래에 있다. 

https://github.com/stan60805/studata/blob/master/IOT/arduino/lib/DHT11/examples/DHT11_test_YD/DHT11_test_YD.pde

 

GitHub - stan60805/studata: test

test. Contribute to stan60805/studata development by creating an account on GitHub.

github.com

해석 끄읕

https://m.blog.naver.com/kji9653/221900031533

 

비트(bit)와 바이트(Byte)란?왜 8비트는 1바이트인가? 킬로바이트(kilobyte)  메가바이트(megabyte) 기가

안녕하세요. 비티샘입니다. 오늘은 우리의 이진법 체계에서 자주 사용하는 비트에 대해 알아보겠습니다. C...

blog.naver.com

위에 링크에 잘 나와있어서 퍼왔음.

 

※ 기초

▶ 1 byte는 8비트로 되어있다.

- 1111 1111 -> 8비트로 표현 가능한 최대 크기

- 0000 0000 -> 8비트로 표현 가능한 최소 크기

 

▶ 1byte는 256가지 표현가능하다.

▶ ASII코드는 127가지가 있다.

- 1 byte로 ASCII코드 하나씩 충분히 표현 가능하다.

https://ko.wikipedia.org/wiki/ASCII

 

ASCII - 위키백과, 우리 모두의 백과사전

1972 프린터 사용 설명서에 개시된 아스키 코드 차트표 미국정보교환표준부호(영어: American Standard Code for Information Interchange), 또는 줄여서 ASCII( , 아스키)는 영문 알파벳을 사용하는 대표적인 문자

ko.wikipedia.org

 

▶ 진수 변환

- 0 또는 1로 표현되면 2진수이다. Binary Code(바이너리)라고 한다.

- 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 로 표현되면 10진수이다. Demical(데미칼)이라고 한다.

- 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , A , B , C , D , E , F 로 표현되면 16진수이다.

HEXADEMICAL(헥사)이라고 한다.

 

https://m.blog.naver.com/icbanq/221727893563

 

[진법변환] 2진수,8진수,10진수,16진수 쉽게 변환하는 방법 알아보기!

안녕하세요~~! 오늘도 여러분들께 유익한 정보를 드리러 온 나도비 입니다 !! 오늘의 주제는 2진수,8진수,1...

blog.naver.com

변환방법은 위 링크에 잘 나와있어서 퍼왔음.

▶ 2진수 -> 16진수

0000 1110의 2진수가 있다.

0000 / 1110의 4비트식 나눠서 계산하면 편하게 16진수를 구할 수 있다.

0 0 0 0 / 1 1 1 0

↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑

(2^3 * 0)+(2^2 * 0)+(2^1*0)+(2^0 * 0) / (2^3 * 1)+(2^2 * 1)+(2^1*1)+(2^0 * 0)

결론 : 0 / E -> 0E 헥사값이 됌
(^ 는 제곱을 의미함)

 

▶ 프로토콜(Protocol)

- 내가 상대방에게 데이터를 보내면 상대방이 무엇이 어떻게 어떤건지를 받는지를 알 수 없는 상태라면 내가 아무리 데이터를 보내도 상대방은 전혀 그 데이터의 내용을 모른다. 그래서 상대방이랑 나랑 같은 방식으로 보내고 받는다면 무슨말인지 알아 들을 수 있을 것이다. 그게 바로 프로토콜이다. (고오오오오급진 말로는 통신규약이다.)

※ 이제 한번 코딩을 해보자.

준비물 : C# , ls-ig5a 인버터 , ls-ig5a-manual , visual studio 2019 community

https://www.ls-electric.com/ko/product/view/P01187

 

LS ELECTRIC

스마트 에너지의 미래를 열어가는 LS ELECTRIC

www.ls-electric.com

ls-ig5a제품설명은 위 링크에 가면 잘 나와있다.

 

우선적으로 인버터랑 시리얼 포트를 연결해야된다.

 

위의 인버터에서 S+,S- 를 RS485 USB 컨버터에 D+,D-로 연결을 해준다.

(S+ → D+ 연결 , S- → D- 연결)

 

그다음 비쥬얼 스튜디오 2019를 켠다. 그다음은 순서대로 하면 됌(여기선 C#으로 함)

ls-ig5a 통신 메뉴얼을 보겠다.

11장 RS-485통신을 누른다.

 

스크롤을 내리다보면 통신선 연결 부분이 있다. 인버터에 설정하는 방법은 메뉴얼 보면 있으니 찾아서 RS-485통신에 맞게 설정해주자.

여기서 사용할 통신 프로토콜은 LS BUS 이다.

 

위의 그림에서 1번은 LS BUS 프로토콜이다.

"" 로 표시된것은 아스키값 , h가 붙은건 헥사값으로 넣으면 된다.

ⓐ ENQ -> 05h -> 1byte 의 뜻은 프로토콜 처음 시작이 ENQ이며 데이터 길이는 1byte이고 05h 는 05라는 hex값으로 넣으라는 의미이다.

ⓑ 국번-> "01" -> 2bytes 뜻은 프로토콜 두번째 시작이 국번이며 데이터 길이는 2bytes이고 "01"의 ASCII문자 값을 넣으라는 의미이다. 시리얼 통신은 1byte식 데이터를 송수신하기 때문에 "01"이 "0"-> 1byte에 저장 , "1" -> 1byte에 저장 하기 때문에 2byte 데이터 길이로 정해진다. 국번은 데이터를 송신할 때 필요한 인버터에게 송신을 하려고 할때 쓰인다. 만약 최대 31개의 인버터가 연결되어있으면 데이터는 다 송신 되지만 정확히 해석하는 인버터는 국번이 맞는 인버터만 해석을 한다. 나머지는 에러 수신을 한다.

ⓒ CMD-> "R" -> 1byte 는 위에 나와있듯이 명령어이다. R은 읽기 W는 쓰기 X는 모니터 등록요구 Y는 모니터 등록 실행. ASCII문자 값을 넣는다.

ⓓ 번지 -> "3000" -> 4bytes는 명령을 내릴 주소(Adress)이다. ASCII문자 값을 넣는다. 메뉴얼 아래에 보면 주소가 나와있다.


ⓔ 번지개수 -> "1"~"8" = n -> 1byte 주소안에 명령을 내릴 데이터의 총 갯수이다. 한꺼번에 명령을 8개나 내릴 수 있다. ASCII문자 값을 넣는다.

SUM ->"A7" -> 2bytes 는 국번 , CMD, 번지 , 번지개수 를 더한값 즉 체크썸을 만든다. ASCII문자 값을 넣는다.(체크썸이란 프로토콜의 신뢰성 즉 데이터가 정확한가에 대해서 한번더 검사하기 위한 것이다.)


예를들어 만드는 방법

  국번 CMD 번지 번지개수 SUM합계
  "01" "R" "3000" "1"  
  "0" "1" "R" "3" "0" "0" "0" "1"  
SUM 30h(헥사) 31h(헥사) 52h(헥사) 33h(헥사) 30h(헥사) 30h(헥사) 30h(헥사) 31h(헥사) 1A7h(헥사)

SUM = 30h + 31h + 52h + 33h + 30h + 30h + 30h + 31h = 1A7h 로 나온다. 하지만 2byte로 적용시켜서 1A7중 1은 없애고 "A7만 넣도록 한다."이제 코딩으로 들어가보자

WinForm하나 만들었다. 이것저것 붙여놨음. C#은 SerialPort 편하게 쓰게 만들어 놨으니 옮겨서 WinForm창에 넣으면 밑에 serialPort1이 생길것이다.

※정회전 통신을 보내 보겠다. 아래를 보도록 하자

foreach(var key in System.IO.Ports.SerialPort.GetPortNames())
{
COMList.Items.Add(key);
}

Winform에서 국번설정 밑에 있는 txtbox가 COMlist이다. 실행시 디바이스에 열려있는 COMPORT를 가져온다.

private void button1_Click(object sender, EventArgs e) 는 Winform에 COM연결이라는 버튼이 있다. 그것이다. 시리얼 포트 열기전 설정을 하고 열어준다.
설정하는 PortName , BaudRate, DataBits , Parity, StopBits는 장치관리자에 연결된 COMPort 속성이 가면 있다.

초기 설정값과 컴포트의 설정하는 값이 동일해야된다. 그래야 시리얼 포트가 열린다.
serialPort1.PortName -> 현재 연결된 COM이름으로 설정
serialPort1.BaudRate -> 비트 / 초랑 맞추며 된다.
serialPort1.Databits -> 데이터 비트랑 맞추면 된다.
serialPort1.Parity -> 패리티랑 맞추면 된다.
serialPort1.StopBits -> 정지 비트랑 맞추면 된다.

데이터를 보내보자.

메뉴얼에 보면 인버터에게 쓰기를 요청하는 프로토콜이 있다. 여기에서 아까 위에서 봤뜻이 형태는 같지만 "데이터"라는게 추가가된다. 똑같이 데이터를 가공해서 붙여주기만 하면 된다.
여기에선 강제로 하드코딩으로 값을 넣어줬다.

(테스트를 할 목적이기 때문에 통신만 된다면 데이터 가공은 능력껏 하면 되기 때문이다.)

여기서 주의할 점은 " " 안에 들어가는 문자들은 헥사값이다. 고로 문자화 된 헥사값을 넣는것이다. 중요하다.

쓰기 요구에 보면 byte가 1개 1데이터만 보내면 총 16바이트가 필요하다. 그래서 위에 바이트 메모리를 16개로 만들어줬다.

ENQ는 05h이기 때문에 헥사값으로 넣어줬다.

ⓒ 국번은 1번지로 인버터에서 세팅 했기 때문에 "01"을 넣어야되지만, 국번 바이트수는 2byte를 넣게 되어있다. 그래서 "0" , "1"을 따로 넣는다. 그리고 "0"은 문자값이기 때문에 byte로 변환시켜줘야된다. C#은 문자값을 byte로 변환해주는 함수가 있다. 이것을 써서 변환해준다.(참고로 "0에 대한 아스키 코드의 16진수값을 넣어도되고 1도 마찬가지이다.)

CMD는 쓰기요구이기 때문에  "W" 값이 들어간다.  아스키코드표를 보면 "W"의 16진수 값이 0x57이다. 이걸 넣어줬다.

번지는 위에 사진에서 보면 파라미터 코드 리스트에 보면 Address가 있을것이다. 운전지령의 Address는 0x0006이다. 그래서 번지자리에 "0","0","0","6"이 들어간다.

번지개수는 1~8개까지 가능한데 "1"을 넣어준이유는 위의 번지를 0006 하나밖에 안넣었기 때문에 1개로 넣어줬다.

데이터는 "0","0","0","2"가 들어간다. 왜 그런지 아래의 사진을 보자.

운전지령의 R/W를 보면 BIT 0 : 정지(0->1)이 되어있다. 이말이 무슨뜻이냐면 1byte는 8bit다. 8bit의 0번째 인덱스 즉 0000 0000 -> 0000 0001 가 되면 정지 지령의 데이터가 된다는 말이다. 이걸 토대로 정방향은 0000 0010 정방향 운전 데이터가 되고, 역방향은 0000 0100 역방향 데이터가 되겠다.

2진수를 16진수로 변환하면 0x00이 정지 , 0x02가 정방향 , 0x04가 역방향이 되겠다. 그러나 위에선 데이터가 4byte로 넣어야되기 때문에 0x0000 , 0x0002 , 0x0004로 되어야된다. (0x00 이나 0x0000이나 똑같음) 여기에선 정방향으로 운전을 하려고 하니 "0","0","0","2"를 넣어줬다.

SUM은 체크썸 값을 넣어준다. 체크썸 값은 ENQ ,SUM , EOT를 제외한 나머지의 값들의 합이다. 고로 국번,CMD,번지,번지개수,데이터 들의 합이다. 다 더하면 625의 정수값(10진수)을 얻을 수 있는데 이것을 HEX로 변환하면 271의 값을 얻을 수 있다. 하지만 체크썸의 값은 2byte고 앞에서 봤듯이 뒤의 자리 2자리만 남기도록 하고있다. 그래서 "7","1"을 넣어줬다.

EOT는 0x04이여서 0x04를 넣어줬다.

마지막으로 bBuffer배열에 바이트를 차례대로 넣어주고 serialPort1.Write(bBuffer , 0 , bBuffer.Length) 를 넣어주면 된다. 뒤에 0이랑 bBuffer.Length는 버퍼의 크기를 설정한다고 생각하면 된다. 0에서 버퍼의 최대크기를 넣는다.

 

이제 주파수를 넣어보자.

주파수를 넣어야되기 때문에 위와 동일한 쓰기 프로토콜로 넣어준다.

ⓐ ENQ ~ 쓰기 까지는 위와 동일하다.

ⓑ 주파수의 지령번지는 0x0005이다. 

ⓒ 번지 개수도 지령번지 1개를 보내기 때문에 위와 동일하다.

ⓓ 데이터는 십진수 2000의 값에 대한 16진수 데이터 0x07D0의 값이 들어간다. 위에서 설명 했다 시피 문자화 된 헥사값을 넣어야 인버터에서 해석을 해 주파수 20.00이 들어간다. 왜 20.00이 들어가냐면 아래의 그림을 보자.

주파수의 단위가 0.01 hz이고 여기 인버터는 00.00hz ~ 60.00 hz를 지원하기 십진수 1을 넣으면 0.01hz가 증가될것이다. 고로 십진수 2000을 넣으면 인버터에서 20.00hz로 변환이 된다. (주파수를 이것저것 넣어 봤는데 최소 00.50hz이상부터 입력이 가능하더군요...)

ⓔ 체크썸도 위와 동일하다. 그래서 값을 구해서 뒤에 두자리만 구하면 "8","9"가 나온다.

 

이제 쓰기는 끝이났다. 어떻게 넣어야 될지를 알기 위해 하드코딩으로 강제로 넣었지만 이제 생각해서 코딩을 짜보길 바란다. 끗

 

+ Recent posts