[NCS 임베디드 SW엔지니어링] 오픈 플랫폼 활용 실습
과정명 | IoT기반 융합 SW 개발자 양성과정 | ||
과목명 | 오픈플랫폼활용(2001020325_16v1 ) | 요소명 | 오픈플랫폼디바이스제어하기 오픈플랫폼APP제어하기 |
수행일자 | 2017년 12.29 ~ 2018년 01.12 | 훈련생 |
|
수행과제 |
아두이노 우노를 이용하여 태스크를 스케치하고 실행하시오. (5점 만점) 개발 환경 구축(1점), 센서 활용(2점), 모터 활용(3점), 쉴드 활용(4점), 통신(5점) jejutour@daum.net 메일로 2018년 1월 19일까지 제출하시오. 필요할 경우 회로를 명시하고 스케치 코드를 설명하시오. |
과제를 통해 확인할 능력 사항 |
- 오픈 플랫폼 개발 환경을 구축할 수 있다. - 단위 모듈 및 공통 모듈의 프로그램을 구현할 수 있다. - 오픈 플랫폼 드라이버를 활용할 수 있고 센서를 제어할 수 있다. - 오픈 플랫폼에서 애플리케이션을 개발할 수 있다. |
수행결과 |
|
예시)
수행결과 |
아두이노 우노 보드와 PC상의 콘솔 응용 프로그램과 통신하는 애플리케이션
제일 먼저 필요한 헤더파일을 포함합니다. /* Simple UDP */ #include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h>
통신에 사용할 포트 번호를 정합니다. 여기에서는 10200 번으로 할게요. const int udp_port = 10200;
UDP 통신을 할 때 사용할 EthernetUDP 형식의 udp 개체를 선언합니다. EthernetUDP udp;
아두이노에서 UDP 통신에 사용할 패킷의 최대 크기는 UDP_TX_PACKET_MAX_SIZE 로 정해졌습니다.
수신하기 위한 버퍼를 선언합니다. char buffer[UDP_TX_PACKET_MAX_SIZE];
여기에서는 패킷을 수신하면 응답으로 약속한 문자열을 전송하기로 할게요. 주의할 점은 맨 마지막 종료 문자는 보내지 않으니 수신하는 곳에서 적절한 처리를 하세요. const char ack_msg[UDP_TX_PACKET_MAX_SIZE]="everyday is a holiday!";
이제 설정 부분입니다. void setup() { 자신의 IP를 확인하는 부분을 작성합시다. 테스트하는데 아두이노 우노의 IP를 모르면 통신을 할 수 없으니 확인하기 쉽게
자신의 IP를 확인하여 시리얼 모니터에 출력하게 합시다. 이에 관한 사항은 아두이노 IP 주소 확인하기를 참고하세요. byte mac[] = { 0xDE, 0xAD, 0x11, 0xEF, 0xFE, 0xED }; EthernetClient client; // Start Serial Serial.begin(9600); while (!Serial) { ; // Wait until connected } //ethernet start if (Ethernet.begin(mac) == 0) { Serial.println("Failed to configure Ethernet using DHCP"); return; }
delay(1000); Serial.println("My IP address"); IPAddress local_ip = Ethernet.localIP(); for (byte addrelem = 0; addrelem < 3; addrelem++) { //print IPv4 Address Serial.print(local_ip[addrelem], DEC); Serial.print("."); } Serial.print(local_ip[3], DEC); Serial.println();
udp 통신을 시작합니다. udp.begin(udp_port);
그리고 시리얼 모니터에 udp 통신을 시작함을 출력합시다. Serial.println("Ready UDP"); Serial.print("Maimum Packet Size :"); Serial.print(UDP_TX_PACKET_MAX_SIZE); Serial.println("bytes."); } 이제 실제 통신 부분입니다.
void loop() {
udp의 멤버 메서드 parsePacket을 호출하면 수신한 패킷 크기를 알 수 있습니다. int psize = udp.parsePacket();
if(psize) {
수신한 패킷 크기가 유효하면 수신한 패킷이 있는 것입니다. 몇 바이트를 수신하였는지 시리얼 모니터에 출력합시다. Serial.print("Received packet : "); Serial.print(psize); Serial.println("bytes.");
udp의 read 메서드를 호출하여 수신한 패킷의 데이터를 프로그램 메모리로 읽어옵니다. udp.read(buffer,UDP_TX_PACKET_MAX_SIZE);
읽어온 데이터를 시리얼 모니터에 출력합시다. Serial.println(buffer);
전송하기 위해 상대 IP와 Port 정보를 입력 인자로 beginPacket 메서드를 호출합니다. udp.beginPacket(udp.remoteIP(), udp.remotePort());
udp의 write 메서드를 호출하여 메시지를 수신하였음을 알려줍니다. 여기에서는 약속한 문자열을 전송할 것입니다. udp.write(ack_msg);
그리고 endPacket 메서드를 호출하여 패킷을 전송합니다. udp.endPacket();
시리얼 모니터에도 전송하였음을 출력합시다. Serial.println("Send Message"); } delay(10); }
다음은 시연화면입니다.
여기에서는 윈도우즈 콘솔 응용 프로그램으로 만들었습니다. 이 부분에 관한 설명은 생략할게요.
//UDP 통신 - PC 용 콘솔 응용 프로그램 // UDP 프로토콜 사용 // 문자열을 입력받아 메시지 전송 후 서버가 보낸 메시지 수신
#pragma warning(disable:4996)
#include <stdio.h> #include <process.h> #include <stdlib.h> #include <WinSock2.h>//윈속 2 사용시 포함할 헤더 #pragma comment(lib,"ws2_32") //윈속 2.2 라이브러리 참조
#define MY_IP "192.168.219.140" //PC IP주소-자신의 환경에 맞게 수정하세요. #define MY_PORT 10200 #define ADU_IP "192.168.219.109" //아두이노 IP 주소-아두이노 시리얼 모니터의 출력값으로 수정하세요. #define ADU_PORT 10200 #define UDP_TX_PACKET_MAX_SIZE 24 int main(void) { WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata);//윈속 초기화
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //1. 소켓생성 if (sock == SOCKET_ERROR) //SOCKET_ERROR는 -1 { fprintf(stderr, "소켓 생성 실패"); return 0; } //2. 소켓과 로컬 소켓 주소 결합(생략 가능) int re = 0; SOCKADDR_IN local_addr = { 0 };//IPv4 소켓 주소 구조체 변수 선언 local_addr.sin_family = AF_INET; //네트워크 주소 체계 설정 local_addr.sin_addr.s_addr = inet_addr(MY_IP);//서버 IP 주소 설정 local_addr.sin_port = htons(MY_PORT);//포트 설정 re = bind(sock, (SOCKADDR*)&local_addr, sizeof(local_addr));
//3. 서버에 연결 요청 re = 0; SOCKADDR_IN adu_addr = { 0 };//IPv4 소켓 주소 구조체 변수 선언 adu_addr.sin_family = AF_INET; //네트워크 주소 체계 설정 adu_addr.sin_addr.s_addr = inet_addr(ADU_IP);//아두이노 IP 주소 설정 adu_addr.sin_port = htons(ADU_PORT);//포트 설정 int len = sizeof(adu_addr); //4. 아두이노와 송수신
char buf[UDP_TX_PACKET_MAX_SIZE];
while (1) { gets_s(buf, sizeof(buf)); re = sendto(sock, buf,strlen(buf)+1, 0,(SOCKADDR *)&adu_addr,sizeof(adu_addr)); printf("%d\n", re); if (strcmp(buf, "exit") == 0) { break; } re = recvfrom(sock, buf, sizeof(buf), 0,(SOCKADDR*)&adu_addr,&len); buf[re] = 0; printf("수신:%s\n", buf); }
//5. 소켓 닫기 closesocket(sock); WSACleanup();//윈속 해제화
return 0; } |
'언어 자료구조 알고리즘 > 프로그래밍 실습' 카테고리의 다른 글
[NCS 실습, SW아키텍처] SW아키텍처 설계하기 (0) | 2018.03.17 |
---|---|
[NCS 임베디드 SW엔지니어링] 임베디드 애플리케이션 설계 (0) | 2018.03.14 |
[NCS 임베디드 SW엔지니어링] 펌웨어 구현 환경 구축 (0) | 2018.03.05 |
[NCS 임베디드 SW엔지니어링] 펌웨어설계 실습 (0) | 2018.02.06 |
[NCS 임베디드 SW엔지니어링] 펌웨어분석 실습 (0) | 2018.01.29 |
[NCS 임베디드 SW엔지니어링 실습] 하드웨어 분석 - 시험 요구사항 도출하기 (0) | 2018.01.06 |
[NCS 임베디드 SW엔지니어링 실습] 하드웨어 분석 - 하드웨어 자료 수집하기 (0) | 2018.01.06 |
[DB 활용 실습] 동적으로 테이블 생성 및 활용 (0) | 2017.12.28 |
[라이브러리 실습] 응용 종류에 종속적이지 않은 라이브러리 만들기 (0) | 2017.12.21 |
[ADO.NET 실습] DB 설계, 저장 프로시저 구현, 응용 프로그램 구현 (0) | 2017.11.10 |