Louie NRT Story

[LTE통신] 한컴텔라딘 소켓 HTTP 연결 본문

전기차충전기

[LTE통신] 한컴텔라딘 소켓 HTTP 연결

hyeok0724.kim@gmail.com 2021. 4. 13. 15:42
반응형

작성일: 21년 4월 13일

 

Index

1. 통신 연결 구조

2. TCP/IP 소켓 연결을 이용한 HTTP 프로토콜 사용

3. STM32F105 코드

4. Cloud Server 코드

5. LapTop에서 Serial Terminal을 통한 데이터 송수신

 

 

1. 통신 연결 구조

1) Laptop 에서 Teladin TX700의 AT 커멘드를 입력함

2) 입력된 정보는 RS485 통신을 통하여 STM32F105 는 수신함

3) STM32F105 에서는 수신된 데이터를 RS232로 변환하여 TX700으로 전달됨

4) TX700에 전달된 정보를 미리 구축해놓은 Cloud Server에 전송되며 수신된 데이터를 웹을 통해 확인 할 수 있음

 

 

2. TCP/IP 소켓 연결을 이용한 HTTP 프로토콜 사용

- 윈도우 C언어로 개발한 코드

- Cloud Server에 TCP/IP 소켓 연결을 한후 HTTP 데이터 GET 요청을 함

- 해당 HTTP 응답이 오도록 함.

#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFSIZE 512

#pragma comment(lib,"ws2_32.lib")

int main()
{
 int retval;
 char buf[BUFSIZE];
 FILE *fp = fopen("test.html", "w");//출력내용을 파일에 저장하기 위해

 //윈속 초기화
 WSADATA wsa;
 if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
  return -1;

 //socket()
 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
 if(sock == INVALID_SOCKET) return 0;

 struct hostent* remoteHost = gethostbyname("3.36.128.36");//웹주소를 ip로 바꾸기 위해
 //connect()
 SOCKADDR_IN serveraddr;
 serveraddr.sin_family = AF_INET;
 serveraddr.sin_port = htons(80);
 serveraddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)*remoteHost->h_addr_list));
 retval = connect(sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr));

 if(retval == SOCKET_ERROR) return 0; 

 char msg[500] = "GET /home HTTP/1.1\r\n";
 strcat(msg,"HOST:3.36.128.36\r\n\r\n");//웹서버로 보낼 헤더 작성 

 
 send(sock, msg, strlen(msg), 0);//웹서버로 보내기

 while(1)
 {
  if((retval = recv(sock, buf, BUFSIZE, 0)) == 0) break;//서버에서 응답 받기
  
  printf("%s", buf);//화면에 출력(너무 많아서 짤려서 보임)
  fprintf(fp, "%s", buf);//파일에 저장

  memset(buf, 0, BUFSIZE);//버퍼 지우기
 }
 closesocket(sock);

 fclose(fp);
 //윈속 종료
 WSACleanup();
 return 0;
}

출처: m.blog.naver.com/PostView.nhn?blogId=sarah7_2000&logNo=80203615486&proxyReferer=https:%2F%2Fwww.google.com%2F

 

- 서버로 부터 온 응답

 

 

3. STM32F105 코드

- UART1은 RS485 통신, UART2는 RS232 통신

- 특별한거는 없고 UART1로 받은 명령어를 UART2로 전달함

- UART2로 받은 명령어를 UART1로 전달함

- White 문을 통하여 수신된 데이터는 모았다가 1초에 한번씩 출력함

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  HAL_GPIO_TogglePin(LED_01_GPIO_Port, LED_01_Pin);
	  //printf("Hello\r\n");
	  //printf("AT$$TCP_NULLPERMISSION?\r\n");

	  HAL_Delay(1000);
	  tx02_transmit();
  }
  /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == USART1)
	{
		HAL_UART_Receive_IT(&huart1, &g_evon_ctrl_rx01_data, 1);

		tx01_data_buffer(g_evon_ctrl_rx01_data);

		//HAL_GPIO_WritePin(UART02_EN_GPIO_Port, UART02_EN_Pin, GPIO_PIN_SET);
		//HAL_UART_Transmit(&huart2, &g_evon_ctrl_rx01_data, 1, 100);
		//HAL_GPIO_WritePin(UART02_EN_GPIO_Port, UART02_EN_Pin, GPIO_PIN_RESET);
	}

	if (huart->Instance == USART2)
	{
		HAL_UART_Receive_IT(&huart2, &g_evon_ctrl_rx02_data, 1);

		tx02_data_buffer(g_evon_ctrl_rx02_data);

		//HAL_GPIO_WritePin(UART01_EN_GPIO_Port, UART01_EN_Pin, GPIO_PIN_SET);
		//HAL_UART_Transmit(&huart1, &g_evon_ctrl_rx02_data, 1, 100);
		//HAL_GPIO_WritePin(UART01_EN_GPIO_Port, UART01_EN_Pin, GPIO_PIN_RESET);
	}
}

uint8_t tx_data[100] = {'\0', };
uint8_t tx_cnt = 0;

void tx01_data_buffer(uint8_t ch){

	tx_data[tx_cnt++] = ch;

	if(ch == '\n'){
		HAL_GPIO_WritePin(UART02_EN_GPIO_Port, UART02_EN_Pin, GPIO_PIN_SET);
		HAL_UART_Transmit(&huart2, &tx_data, tx_cnt, 100);
		HAL_GPIO_WritePin(UART02_EN_GPIO_Port, UART02_EN_Pin, GPIO_PIN_RESET);

		tx_cnt = 0;
	}
}

uint8_t tx02_data[100] = {'\0', };
uint8_t tx02_cnt = 0;

void tx02_data_buffer(uint8_t ch){
	tx02_data[tx02_cnt++] = ch;
}

void tx02_transmit(){
	if(tx02_cnt != 0){
		HAL_GPIO_WritePin(UART01_EN_GPIO_Port, UART01_EN_Pin, GPIO_PIN_SET);
		HAL_UART_Transmit(&huart1, &tx02_data, tx02_cnt, 100);
		HAL_GPIO_WritePin(UART01_EN_GPIO_Port, UART01_EN_Pin, GPIO_PIN_RESET);
		tx02_cnt = 0;
	}
}

 

 

4. Cloud Server 코드

- Flask Framework로 간단하게 구현함

- main.py

from flask import Flask, render_template
  
app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/home')
def hello():
    return render_template('hello.html')

if __name__ == '__main__':
    app.run(host="0.0.0.0", port="80", debug=False)

- hello.html

<!DOCTYPE html>
<html>
        <head>
                    <meta charset="UTF-8">
        </head>
        <body>
                <h1>Heelo.html</h1>
        </body>
</html>

 

 

5. LapTop에서 Serial Terminal을 통한 데이터 송수신

1) LapTop에서 AT명령어를 TCP/IP 소켓 연결을 시도후 성공함

2) HTTP GET 요청을 통하여 데이터를 수신함을 확인함

 

※ 주의 사항

'\r\n' 이 데이터가 C언어 소켓에서는 0x0D 0x0A로 수정되어 전송이 되지만 내가 사용하는 터미널에서는 '\'와 'r', 'n' 하나씩 모두 아스키코드로 변환되어 애초에 전송되는 데이터가 잘못 되어있었다.

그래서 Hex 값으로 변환하여 터미널을 통해 처음부터 HEX 값으로 전송함

 

TCP/IP 소켓 연결 AT 커멘드

AT$$TCP_SCOP
41 54 24 24 54 43 50 5f 53 43 4f 50 0D 0A

 

HTTP GET 요청 명령어
GET /home HTTP/1.1\r\nHOST:3.36.128.36\r\n\r\n
47 45 54 20 2f 68 6f 6d 65 20 48 54 54 50 2f 31 2e 31 0D 0A 48 4f 53 54 3a 33 2e 33 36 2e 31 32 38 2e 33 36 0D 0A 0D 0A

 

TCP/IP 소켓 연결해제 AT 커멘드

AT$$TCP_SCCL
41 54 24 24 54 43 50 5f 53 43 43 4c 0D 0A

 

※ 개발자 시부렁시부렁

NULLPERMISSION 이 모두 0 으로 되어 있어야 했다.

기존에 0, 1 이게 뭔지는 모르겠지만 설정이 0, 0 으로 되어 있지 않아서 데이터 송수신이 되지 않았음.

그것도 모르고 왜 데이터가 안가는지 6시간동안 삽질했다.

반응형
Comments