본문 바로가기
프로그래밍/MFC (C++)

MFC ] 시리얼 통신으로 LED 제어하기 (3) + MySQL (IoT)

by eteo 2022. 7. 17.

 

STM32 → UART 수신 인터럽트로 '1'이 들어오면 LED를 켜고 '0'이 들어오면 LED를 끈다.

MFC → 외부 DB에 접속해 '1' 또는 '0'이 들어있는 1행1열의 테이블을 타이머를 사용해서 0.5초 간격으로 읽어오고 해당 값을 STM32에 시리얼 통신으로 송신한다.

 

 

 

 

 

 

STM32 수신 인터럽트 부분

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART3){

		if(rx=='1'){
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, 1);
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 1);
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 1);

		}else if(rx=='0'){
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, 0);
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0);
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 0);
		}
		HAL_UART_Receive_IT(&huart3, &rx, 1);
	}

}
/* USER CODE END 4 */

 

 

 

 

 

MFC앱

 

CMysqlController.h 의 DB 접속을 위한 정보를 수정한다.

실습시 같은 네트워크망 내에 있어서 그냥 아이피를 적으면 됐는데 외부 네트워크에 있는 DB 접속을 위해선 포트포워딩 과정이 필요할 것 같다.

 

 

 

 

 

Timer의 Set과 Kill

타이머에서 수행하는 작업 자체가 시리얼 포트가 열려야만 의미있는 일이기 때문에 포트가 열린 후에 SetTimer()를 호출하고 포트가 닫히기 전에 KillTimer()를 호출한다.

 

 

void CMFCSerialCommDlg::OnBnClickedBtConnect()
{
	// TODO: Add your control notification handler code here
	if (comport_state)
	{
		if (m_comm)        //컴포트가존재하면
		{
			KillTimer(0);
			m_comm->Close();
			m_comm = NULL;
			AfxMessageBox(_T("COM 포트닫힘"));
			comport_state = false;
			GetDlgItem(IDC_BT_CONNECT)->SetWindowText(_T("OPEN"));
			GetDlgItem(IDC_BT_SEND)->EnableWindow(false); //버튼 비활성화			
		}
	}
	else
	{
		m_comm = new CSerialComm(_T("\\\\.\\") + m_str_comport, m_combo_baudrate, _T("None"), _T("8 Bit"), _T("1 Bit"));         // initial Comm port
		if (m_comm->Create(GetSafeHwnd()) != 0) //통신포트를열고윈도우의핸들을넘긴다.
		{
			AfxMessageBox(_T("COM 포트열림"));
			comport_state = true;
			GetDlgItem(IDC_BT_CONNECT)->SetWindowText(_T("CLOSE"));
			GetDlgItem(IDC_BT_SEND)->EnableWindow(true); //버튼 클릭할 수 있는 상태
			SetTimer(0, 500, NULL);
		}
		else
		{
			AfxMessageBox(_T("ERROR!"));
		}
	}
}

 

SetTimer() 함수의 매개변수는 임의의 ID번호, 밀리초 단위 간격, 그리고 마지막 매개변수로 함수 포인터를 넣으면 해당 함수가 호출되고 NULL을 넣으면 WM_TIMER 메시지 처리 함수인 OnTimer() 함수로 들어온다.

KillTimer() 함수의 인수로 ID를 넣으면 해당 타이머가 종료된다.

 

 

 

 

OnTimer() 함수 내부

void CMFCSerialCommDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	CMysqlController conn;
	CString Onoff = _T("");

	if (conn.SelectQuery("select * from contb", Onoff) == true) {}

	m_comm->Send(Onoff, Onoff.GetLength());

	CDialogEx::OnTimer(nIDEvent);
}

 

DB에 쿼리문을 보내 값을 읽고 그대로 STM32로 송신한다.