STM32 와이파이 모듈 사용 - ESP8266

저렴한 와이파일 모듈로 ESP8266 많이 사용한다고 하여, 지인에게 여분의 ESP8266 모듈 얻어 일주일동안 토나올 정도로 아주 제대로 꽃삽질을 하였다.

 

STM32 보드에 ESP 와이파일 모듈을 내장한 보드라면 ESP 모듈을 직접 제어하고 ESP에서 제공하는 라이브러리 사용하여 소켓프로그램을 할 수 있겠지만, STM32 Discovery 데모보드를 사용하고 있는 나로썬, UART로 ESP 마이컴과 통신하여 와이파이를 제어할 수밖에 없다.

 

지인에게 얻은 ESP8266 모듈에는 마이컴이 내장되어 있고, 양산용 펌웨어가 아닌 디버그 펌웨어가 올라가 있어 UART 통신 과정에서 수많은 예외상황이 발생하여 삽질의 연속이었다. 디버그 메시지로 UART RX 인터럽트가 빈번하게 발생하여 오버헤드로 인한 UART 데이터가 유실되는 문제까지 생겨 좀 고생을 하였다.

위 이미지와 같이 STM32의 UART2는 PC와 시리얼 통신하는 UART 포트로 설정하였고, UART3는 ESP8266 모듈의 마이컴과 통신하는 UART 포트로 설정하였다.

인터럽트 발생빈도를 줄이기 위해 사용자가 입력하는 콘솔을 Polling 방식을 사용하였고, ESP 마이컴에서 수신하는 데이터는 인터럽트 방식으로 설정하였다. UART3 포트도 Polling 방식으로 설정하였으나, ESP 모듈로 Command 전송 후 바로 Polling 방식으로 UART3 RX 데이터를 체크할 경우 데이터가 제대로 들어오지 않아 인터럽트로 변경하였다. 이 부분은 HAL 라이브러리 코드를 나중에 살펴봐야 할 것 같다.

CubeIDE를 사용하여 STM32F407VG의 Pin 설정을 위 이미지와 같이 하였으며, Blue 버튼 인터럽트로 PA0를 설정하여 ESP 모듈의 TCP 서버를 종료시킬 예정이다. GitHub에 소스코드를 올려놓았으며 아래 링크에 전체 코드가 있다.

 

highgon2/STM32

STM32 TestCode. Contribute to highgon2/STM32 development by creating an account on GitHub.

github.com

UART3 포트는 인터럽트로 설정하였기 때문에 ESP로부터 데이터가 수신될 때마다 ISR 실행하면 시스템의 오버헤드가 발생하기 때문에 수신 데이터를 버퍼에 저장하고 버퍼 오버플로우가 발생하면 Red LED를 토글 시키도록 하였다.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART3)
    {
        if(cb_data.length < MAX_UART_RX_BUFFER)
            cb_data.buf[cb_data.length++] = data;
        else
            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
        HAL_UART_Receive_IT(huart, &data, 1);
    }
}

그리고 ESP 모듈에 AT Command를 보내고 응답을 기다리는 코드를 아래와 같이 작성하였다. 여기서 한참동안 삽질한 이유가 'OK' 또는 'ERROR' 응답을 받고 대기(HAL_Delay)없이 바로 다음 AT Command를 실행하면 ESP 모듈이 오동작하는 현상 때문에 하루종일 삽질을 하였다.

static int esp_at_command(uint8_t *cmd, uint8_t *resp, uint16_t *length, int16_t time_out)
{
    *length = 0;
    memset(resp, 0x00, MAX_UART_RX_BUFFER+1);
    memset(&cb_data, 0x00, sizeof(cb_data_t));
    if(HAL_UART_Transmit(&huart3, cmd, strlen((char *)cmd), 100) != HAL_OK)
        return -1;

    while(time_out > 0)
    {
        if(cb_data.length >= MAX_UART_RX_BUFFER)
            return -2;
        else if(strstr((char *)cb_data.buf, "ERROR") != NULL)
            return -3;
        else if(strstr((char *)cb_data.buf, "OK") != NULL)
        {
            memcpy(resp, cb_data.buf, cb_data.length);
            *length = cb_data.length;
            break;
        }

        time_out -= 10;
        HAL_Delay(10);
    }

    HAL_Delay(500);     
    return 0;
}

STM32에서 ESP 모듈을 직접 제어하는 것이 아니라 ESP 모듈에 내장된 마이컴으로 명령어를 요청하고 그것에 결과를 을 받아 처리하는 구조이기 때문에 모든 것이 매끄럽지 않지만, 결과를 받고 바로 다음 명령어를 보내면 ESP에서 처리를 못하는 현상이 있다. ESP 펌웨어가 개발버전이라서 발생한 문제인지 모르겠으나, 이것 때문에 고생한거 생각하면.... ;;

GitHub의 BoardTest 디렉토리는 콘솔 명령어로 각 모듈별 테스트 및 기능 검증 코드를 작성할 예정인데, 많은 모듈을 붙여서, 위 이미지에서 기능 테스트 항목이 많이 늘어났으면 좋겠다.

 

어쨌뜬, ESP의 AT Command 명령어를 사용하여 TCP 서버를 시작하여 PC에서 파이썬으로 Hello 메시지를 보낸것이 STM32에서 출력되는 것을 확인하였다. 이것을 바탕으로 PC 프로그램이나 웹에서 STM32 보드를 제어하는 앱을 간단하게 만들볼 생각이다.