이번 리눅스 실습을 통해서 Apache2(웹 서버)를 활용해 StepMotor를 제어해봤습니다. 이를 위해 우선 웹과 웹서버의 차이를 알아야합니다.
클라이언트의 입장에서는 웹 서버에게 주소(URL)을 가지고 통신규칙(HTTP)에 맞게 요청하면 알맞은 내용(HTML)을 응답 받습니다.
서버의 입장에서는 클라이언트의 요청을 기다리고, 웹 요청(HTTP)에 대한 데이터를 만들어서 응답합니다. 이 때 데이터는 웹에서 처리할 수 있는 HTML,CSS,이미지 등 정적인 데이터로 한정짓습니다.
우리또한 로컬 컴퓨터로 쉽게 웹 서버를 만들 수 있습니다. 무료로 공개된 Apache 웹 서버를 통해서 Port Number와 HTML파일 위치를 정해주면 전세계 사람들에게 웹 서비스를 제공할 수 있는 컴퓨터를 가질 수 있습니다.
하지만 웹 서버에서는 HTML,CSS,이미지 등 정적인 자료만 제공 할 수 있습니다. 예를 들면 무엇인가를 설명하기 위한 정보를 제공한다고 하면 설명의 내용을 모두 작성해놔야합니다. 이 설명의 내용이 길어지게 되면 직접 작성해야하므로 문제가 여간 까다로운것이 아니다.
다시 말해서, 웹 서버에서 브라우저에게 HTML을 주기 전에 어플을 돌려서 데이터를 만들고 그 데이터를 넣어 주면 간단하지만 HTML은 프로그래밍 언어가 아니기에 위 문제를 해결할 수 없습니다.
결국 요청에 따른 비지니스 로직 처리나 DB 연동 문제를 해결하기위해 등장한 것이 WAS입니다.

우선 Apache2를 라즈베리파이의 설치합니다.
그리고 Loop Back IP주소를 라즈베리파이의 인터넷 주소창에 입력하고 접속을 하면 라즈베리파이 가상환경에서 접속중인 Apache2의 화면에 접속할 수 있습니다. 그리고 내가 사용하고 있는 라즈베리파이의 IP주소를 Window의 Chrome을 통해 접속하면 라즈베리에서 접속중인 Apache2를 window에서도 접속할 수 있습니다.
우리는 이 CGI파일을 사용해서 동적인 웹 페이지를 만든 뒤 웹 페이지에서 StepMotor를 제어해보는것이 목표입니다.
이를 위해 우선 우리는 라즈베리파이에 존재하는var/www/html파일에cgi-bin파일을 생성해 cgi파일들을 생성할 것 입니다.
우리는 cig파일들을 라즈베리파이의 개발환경 "Genie"를 통해서 간편하게 수정하기 위해 권한 설정을 해줘야합니다. 이는 보안에 취약하기때문에 추후에 배포를 할 때에는 권한 설정을 재설정해줘야합니다.권한 설정을 편하게 하기위해서는 다음과 같은 명령어를 사용합니다.


- 다음 처럼
test.html을 만들어 저장을 하고, 2번째 사진처럼 윈도우의 ip주소의 옆에test.html로 들어가게 되면 내가 저장한test.html에 저장된 내용이 웹에 나타난다.hello.html
hello.html으로 input버튼을 만들어준 화면에 입력버튼을 누르면 실행되는 html코드를test.c로 만든 실행파일을 연결해주면 다음처럼 실행파일이 실행됩니다.
- 라즈베리파이의 dev 디렉토리에 있는 gpiomem의 권한을 수정해줍니다. 이는 gpio핀 권한을 수정해줘서 웹을 통해서 HW조절이 가능하도록 권한을 수정해주면 웹에서 submit를 하면 LED가 켜집니다.
- 다음과 같이 CGI명령어를 활용해 address와 querystring을 화면에 보여줄 수 있다.
결과를 보면 주소가 변경되었음을 확인 할 수 있다. 입력창에 1234를 입력하고 submit버튼을 눌렀더니 다음과 같이 submit버튼이 눌렸고 입력(value)에는 1234가 입력되었음을 확인할 수 있다.
- 우리가 웹 사이트에서 input에 입력한 값을 사용해 HW를 제어하는데 보면 Query String의 값은 다음처럼 문자열로 나오는 것을 확인할 수 있습니다. 우리는 value(input)의 값만 사용하려면 아래와 같은 함수를 만들어 사용하면 input의 문자열 값을 정수형태로 변경하여 활용이 가능합니다.
![]()
GetToken()함수를 이용해서 우리는main함수에서getenv()함수를 사용해서 웹 서버의 환경변수 값을 가져옵니다 이를 포인터를 사용해서 주소 값을 받아서GetToken()에 넘겨주면 이 문자열의 길이 만큼 반복문을 실행합니다. 여기서 환경변수 값은 '='과 '&'로 값을 받거나 input명과 값을 같이 가져올 수 도 있습니다. 그러한 이유로 구분자를 구분하여 구분자와함께 값을 추출하거나 구분자 뒤의 값만을 추출하는 기능을 수행합니다.
만약 내가 위의 "Query String : value=1234&button=submit"에서 "1234"를 추출한다면 i = 10일때 count가 증가하게될 것이다. 이때 GetToken()함수에서 n의 매개변수에 0을 입력했다면 우리는 받아온 환경변수의 '&' 기준으로 첫번째 값을 0번이라고 합니다. 그렇다면 0을 입력했다는 의미는 환경 변수 값의 가장 첫번째인 "value=1234"의1234값이 필요하다는 의미입니다. 만약 이렇게 되면 else if문의(count == n+1)의 조건문에 만족하여 k 의 값은 10가 될 것이고. j = 0이므로 if(j)가 거짓이므로 j++는 실행되지 않습니다. 그리고 동적할당하여 크기를 정한 ret이라는 char배열에 받아온 환경변수 값의 문자열의 0번째 부터 10번째까지 ret 문자열 포인터에 할당됩니다. 그래서 결과적으로 "value=1234" 라는 결과가 출력됩니다.결과
- ASCII코드를 정수로 변환하는 함수





StepMotor 구동방식
출처 : StepMotor 관련 내용


StepMotor를 CGI(Apache2)를 사용해 웹에서 값을 줘서 동작을 하도록 실습했습니다. 이전 실습에서 사용한 cgi통신의 GetToken() 함수를 가져와서 사용했습니다. GetToken()함수는 QUERY_STRING으로 받아오는 값(문자열)을 값만 우리가 뽑아서 사용할 수 있게하는 함수입니다. 이 값은 문자열이므로 우리가 이전에 사용한 atoi()함수를 통해서 받은 문자열을 정수로 전환해주게되면(mode, msec_time) 그 값이 steps[mode - 1]에 들어가게 됩니다. StepMotor의 구동방식은 3가지가 존재합니다.그렇기 때문에 mode에는 1~3까지의 입력만 입력할 수 있기때문에 steps[0]~steps[2] 까지 4,4,8의 값이다 이는 wave, half에는 4개의 case만이 존재하고 half에는 8개의 case가 존재하기 때문에 다음과 같이 steps 배열을 사용한 것이다. 첫번째 반복문(for(int i = 0; i<steps[mode -1]; i++))에서는 선택된 mode의 case를 모두 실행시키도록 하기위한 반복문입니다(만약 Mode에 1을 할당한다면 steps[0], 즉 4만큼 반복문을 실행하고 1번 모드인 wave모드가 실행됩니다 wave모드는 4가지 case가 존재합니다!). 이 값은 우리가 CGI통신으로 값을 입력하면 StepMotor가 동작하고 StepMotor가 동작하는 while문은 millis() 함수를 통해서 라즈베리파이에 내장되어있는 m_sec카운터(m_counter)를 통해서 while반복문을 만나기전까지 시간을 total_time에 할당하고 while반복문을 만나기 전에 저장한 시간과 계속 카운트되는 millis()함수의 값을 빼서 CGI통신으로 웹에서 주는 시간의 값보다 작아지게 되면 while문을 빠져나오도록 하였습니다.
위의 과정을 거치면 웹서버에서 입력값을 주면 라즈베리파이에 연결한 StepMotor가 동작하는 것을 확인할 수 있습니다!
휴대폰으로 라즈베리파이의 IP에 접속하여 휴대폰에서 step모터를 제어하도록 하는 실습도 진행했습니다. 다만 교육장에서 라즈베리파이의 통신을 위해 사용되는 통신망을 사용하고 있기 때문에 휴대폰과 이 통신망을 와이파이를 통해 접속 을 한뒤 와이파이의 주소를 수동으로 IP주소를 입력해서 접속을 해야만 휴대폰에서 라즈베리파이의 동작을 수행할 수 있습니다. 이렇게 IOT관련 실습도 진행할 수 있었습니다
