[STM32#20] usart1에 esp01을 연결해서 wifi에 연결하고 mqtt프로토콜을 이용해서 데이터를 전송하는 방법 알아보기!(녹칸다 내맘대로 STM32)
프로그래밍/STM32 2025. 12. 17. 16:55반응형

https://youtube.com/live/vxvtke2AAUc
[STM32#20] usart1에 esp01을 연결해서 wifi에 연결하고 mqtt프로토콜을 이용해서 데이터를 전송하는 방법 알아보기!(녹칸다 내맘대로 STM32)
심심한녹칸다의 내맘대로 STM32시리즈이다!
STM32시리즈의 모든 자료는 구글 슬라이드에 작성하고 모두에게 공유되어있음!
https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a6f1f77138_2_233#slide=id.g3a6f1f77138_2_233
STM32에서 sscanf와 ring buffer를 활용해봅시당!




1.STM32에서 ESP01에 AT커맨드를 전송할때 제대로 전송되었는지를 확인할 수 있는 코드를 작성하시요!(테스트용코드)

/* USER CODE BEGIN 0 */
char cmd1[] = "AT\r\n";
char cmd2[] = "ATE0\r\n";
char mode_set[] = "AT+CWMODE=1\r\n";
char ap_con[] = "AT+CWJAP=\"popcorn\",\"11213144\"\r\n";
char ap_discon[] = "AT+CWQAP\r\n";
char tcp_con[] = "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n";
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ring_buffer[head++] = data;
if(head == b_size) head = 0;
HAL_UART_Receive_IT(&huart1, &data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
if(head != tail){
char data = ring_buffer[tail];
HAL_UART_Transmit(&huart2, &data, 1, 100);
tail++;
if (tail == b_size) tail = 0;
}
}
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &data, 1); //수신인터럽트
HAL_TIM_Base_Start_IT(&htim2); //타이머인터럽트
char u2_data;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//usart2로 녹칸다가 문자 '1'을 전송하면 AT커맨드를 전송한다!
if(HAL_UART_Receive(&huart2, &u2_data, 1, 100) == HAL_OK){
if(u2_data == '1'){
//생존확인
HAL_UART_Transmit(&huart1, cmd1, strlen(cmd1), 100);
}else if(u2_data == '2'){
//echo off
HAL_UART_Transmit(&huart1, cmd2, strlen(cmd2), 100);
}else if(u2_data == '3'){
//스테이션 모드로 변경
HAL_UART_Transmit(&huart1, mode_set, strlen(mode_set), 100);
}else if(u2_data == '4'){
//인터넷공유기에 접쏙!
HAL_UART_Transmit(&huart1, ap_con, strlen(ap_con), 100);
}else if(u2_data == '5'){
//인터넷공유기 접속 해제!
HAL_UART_Transmit(&huart1, ap_discon, strlen(ap_discon), 100);
}else if(u2_data == '6'){
//브로커와 TCP 연결하기
//MQTT브로커와 TCP연결한다음, MQTT연결 명령어를 시간내 전송안하면
//서버가 자동으로 연결을 끊어버린다!
HAL_UART_Transmit(&huart1, tcp_con, strlen(tcp_con), 100);
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
2.MQTT브로커랑 접속하고 녹칸다가 준비해놓은 기본 예제를 작동시켜보시오!

/* USER CODE BEGIN 0 */
char cmd1[] = "AT\r\n";
char cmd2[] = "ATE0\r\n";
char mode_set[] = "AT+CWMODE=1\r\n";
char ap_con[] = "AT+CWJAP=\"popcorn\",\"11213144\"\r\n";
char ap_discon[] = "AT+CWQAP\r\n";
char tcp_con[] = "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n";
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ring_buffer[head++] = data;
if(head == b_size) head = 0;
HAL_UART_Receive_IT(&huart1, &data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
if(head != tail){
char data = ring_buffer[tail];
HAL_UART_Transmit(&huart2, &data, 1, 100);
tail++;
if (tail == b_size) tail = 0;
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &data, 1); //수신인터럽트
HAL_TIM_Base_Start_IT(&htim2); //타이머인터럽트
char u2_data;
uint8_t msg[256];
//연결 해제
HAL_UART_Transmit(&huart1,ap_discon,strlen(ap_discon),100);
HAL_UART_Transmit(&huart2,"AP DIS CON\r\n",12,100);
HAL_Delay(2000); //2초정도 기다리면 되겠지?
//연결
HAL_UART_Transmit(&huart1,ap_con,strlen(ap_con),100);
HAL_UART_Transmit(&huart2,"AP CONNECTING\r\n",15,100);
HAL_Delay(10000);
//브로커 접속
HAL_UART_Transmit(&huart1,tcp_con,strlen(tcp_con),100);
HAL_UART_Transmit(&huart2,"BROKER CONNECTING\r\n",19,100);
HAL_Delay(5000);
//MQTT 연결
uint8_t num1 = (HAL_GetTick()/1000) %10;
uint8_t num2 = (HAL_GetTick()/100) %10;
uint8_t num3 = (HAL_GetTick()/10) %10;
uint8_t num4 = HAL_GetTick() %10;
uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_CONNECT));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(1000);
HAL_UART_Transmit(&huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
HAL_UART_Transmit(&huart2,"MQTT SET\r\n",10,100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
uint8_t MQTT_MSG[50];
sprintf(MQTT_MSG,"STM32 HAL_GetTick()=%d",HAL_GetTick());
MQTT_PUBLISH[13] = strlen(MQTT_MSG);
MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(500);
HAL_UART_Transmit(&huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
HAL_UART_Transmit(&huart1,MQTT_MSG,strlen(MQTT_MSG),100);
HAL_UART_Transmit(&huart2,"publish\r\n",9,100);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
//전역으로 클래스선언
MqttClient client;
string clientId;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//메인폼이 로드되어서 사용자 눈에 딱 보였다!
//MQTT 브로커와 연결하는 부분
string BrokerAddress = "broker.emqx.io";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
richTextBox1.Text += "접속완료\n";
//접속이 완료된 위치
//Subscribe Topic 추가
string[] mytopic = { "NOCKANDA" };
byte[] qos = { 0 };
client.Subscribe(mytopic, qos);
richTextBox1.Text += "구독완료\n";
}
//MQTT이벤트 핸들러
void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
//DO SOMETHING..!
richTextBox1.Text += "[수신] " + ReceivedMessage + "\n";
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//사용자가 프로그램을 껐다!
//MQTT 연결 종료
client.Disconnect();
}
3.녹칸다의 STM32쉴드에 PA0에 붙어있는 가변저항값을 12bit로 측정해서 MQTT로 C#윈폼에 전송한다음 화면에 출력하시오!

/* USER CODE BEGIN 0 */
char cmd1[] = "AT\r\n";
char cmd2[] = "ATE0\r\n";
char mode_set[] = "AT+CWMODE=1\r\n";
char ap_con[] = "AT+CWJAP=\"popcorn\",\"11213144\"\r\n";
char ap_discon[] = "AT+CWQAP\r\n";
char tcp_con[] = "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n";
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ring_buffer[head++] = data;
if(head == b_size) head = 0;
HAL_UART_Receive_IT(&huart1, &data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
if(head != tail){
char data = ring_buffer[tail];
HAL_UART_Transmit(&huart2, &data, 1, 100);
tail++;
if (tail == b_size) tail = 0;
}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &data, 1); //수신인터럽트
HAL_TIM_Base_Start_IT(&htim2); //타이머인터럽트
HAL_ADC_Start(&hadc1); //딱 한번만 호출
uint16_t adc_value0 = 0;
char u2_data;
uint8_t msg[256];
//연결 해제
HAL_UART_Transmit(&huart1,ap_discon,strlen(ap_discon),100);
HAL_UART_Transmit(&huart2,"AP DIS CON\r\n",12,100);
HAL_Delay(2000); //2초정도 기다리면 되겠지?
//연결
HAL_UART_Transmit(&huart1,ap_con,strlen(ap_con),100);
HAL_UART_Transmit(&huart2,"AP CONNECTING\r\n",15,100);
HAL_Delay(10000);
//브로커 접속
HAL_UART_Transmit(&huart1,tcp_con,strlen(tcp_con),100);
HAL_UART_Transmit(&huart2,"BROKER CONNECTING\r\n",19,100);
HAL_Delay(5000);
//MQTT 연결
uint8_t num1 = (HAL_GetTick()/1000) %10;
uint8_t num2 = (HAL_GetTick()/100) %10;
uint8_t num3 = (HAL_GetTick()/10) %10;
uint8_t num4 = HAL_GetTick() %10;
uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_CONNECT));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(1000);
HAL_UART_Transmit(&huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
HAL_UART_Transmit(&huart2,"MQTT SET\r\n",10,100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
{
adc_value0 = HAL_ADC_GetValue(&hadc1);
}
uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
uint8_t MQTT_MSG[50];
sprintf(MQTT_MSG,"%d,%d",msg_num,adc_value0);
msg_num++;
MQTT_PUBLISH[13] = strlen(MQTT_MSG);
MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(500);
HAL_UART_Transmit(&huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
HAL_UART_Transmit(&huart1,MQTT_MSG,strlen(MQTT_MSG),100);
HAL_UART_Transmit(&huart2,"publish\r\n",9,100);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
//전역으로 클래스선언
MqttClient client;
string clientId;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//메인폼이 로드되어서 사용자 눈에 딱 보였다!
//MQTT 브로커와 연결하는 부분
string BrokerAddress = "broker.emqx.io";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
richTextBox1.Text += "접속완료\n";
//접속이 완료된 위치
//Subscribe Topic 추가
string[] mytopic = { "NOCKANDA" };
byte[] qos = { 0 };
client.Subscribe(mytopic, qos);
richTextBox1.Text += "구독완료\n";
}
//MQTT이벤트 핸들러
void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
//DO SOMETHING..!
richTextBox1.Text += "[수신] " + ReceivedMessage + "\n";
string[] data = ReceivedMessage.Split(',');
if(data.Length == 2)
{
textBox1.Text = data[0];
textBox2.Text = data[1];
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//사용자가 프로그램을 껐다!
//MQTT 연결 종료
client.Disconnect();
}
4.STM32쉴드에 붙어있는 온습도센서인 DHT-11의 값을 측정해서 MQTT로 C#윈폼에 전송한다음 화면에 출력하시오!

/* USER CODE BEGIN 0 */
char cmd1[] = "AT\r\n";
char cmd2[] = "ATE0\r\n";
char mode_set[] = "AT+CWMODE=1\r\n";
char ap_con[] = "AT+CWJAP=\"popcorn\",\"11213144\"\r\n";
char ap_discon[] = "AT+CWQAP\r\n";
char tcp_con[] = "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n";
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ring_buffer[head++] = data;
if(head == b_size) head = 0;
HAL_UART_Receive_IT(&huart1, &data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
if(head != tail){
char data = ring_buffer[tail];
HAL_UART_Transmit(&huart2, &data, 1, 100);
tail++;
if (tail == b_size) tail = 0;
}
}
#define delay_ms HAL_Delay
#define SYS_CLOCK 64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt & 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick->VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) { // 64MHz 보정
if (us > 1) {
uint32_t count = us * 7 - 6;
while (count--);
} else {
uint32_t count = 2;
while (count--);
}
}
union {
uint32_t data;
struct {
uint8_t temp_d;
uint8_t temp_i;
uint8_t rh_d;
uint8_t rh_i;
};
} DHT;
uint8_t DHT_read () {
uint8_t i, check_sum;
uint32_t start;
check_sum = 0;
DHT.data = 0;
GPIOC->CRL = (GPIOC->CRL&0xFFFFFF0F)|(7<<(1*4)); // Output Open-drain (Master send LOW signal)
delay_ms(18);
GPIOC->CRL= (GPIOC->CRL&0xFFFFFF0F)|(4<<(1*4)); // Floating input (Master send HIGH signal & data receive)
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 50) return 1; // 20~40us
}
start = micros();
while (!(GPIOC->IDR&(1<<1))) {
if (micros()-start > 120) return 2; // 80us
}
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 120) return 3; // 80us
}
for (i = 0; i < 32; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) DHT.data |= (0x80000000 >> i); // "0"=26~28us, "1"=70us
}
for (i = 0; i < 8; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) check_sum |= (0x80 >> i);
}
if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
else return 4;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &data, 1); //수신인터럽트
HAL_TIM_Base_Start_IT(&htim2); //타이머인터럽트
HAL_ADC_Start(&hadc1); //딱 한번만 호출
uint16_t adc_value0 = 0;
char u2_data;
uint8_t msg[256];
//연결 해제
HAL_UART_Transmit(&huart1,ap_discon,strlen(ap_discon),100);
HAL_UART_Transmit(&huart2,"AP DIS CON\r\n",12,100);
HAL_Delay(2000); //2초정도 기다리면 되겠지?
//연결
HAL_UART_Transmit(&huart1,ap_con,strlen(ap_con),100);
HAL_UART_Transmit(&huart2,"AP CONNECTING\r\n",15,100);
HAL_Delay(10000);
//브로커 접속
HAL_UART_Transmit(&huart1,tcp_con,strlen(tcp_con),100);
HAL_UART_Transmit(&huart2,"BROKER CONNECTING\r\n",19,100);
HAL_Delay(5000);
//MQTT 연결
uint8_t num1 = (HAL_GetTick()/1000) %10;
uint8_t num2 = (HAL_GetTick()/100) %10;
uint8_t num3 = (HAL_GetTick()/10) %10;
uint8_t num4 = HAL_GetTick() %10;
uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_CONNECT));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(1000);
HAL_UART_Transmit(&huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
HAL_UART_Transmit(&huart2,"MQTT SET\r\n",10,100);
int msg_num = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint8_t error_no = DHT_read();
if(error_no == 0){ // 정상일 때 처리
float temp = 0;
float humi = 0;
temp = DHT.temp_i;
if (DHT.temp_d & 0x80) {
temp = -1 - temp;
}
temp += (DHT.temp_d & 0x0f) * 0.1;
humi = DHT.rh_i + DHT.rh_d * 0.1;
uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
uint8_t MQTT_MSG[50];
sprintf(MQTT_MSG,"%d,%.2f,%.2f",msg_num,temp,humi);
msg_num++;
MQTT_PUBLISH[13] = strlen(MQTT_MSG);
MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(500);
HAL_UART_Transmit(&huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
HAL_UART_Transmit(&huart1,MQTT_MSG,strlen(MQTT_MSG),100);
HAL_UART_Transmit(&huart2,"publish\r\n",9,100);
} else {
//측정실패
}
HAL_Delay(1500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
//전역으로 클래스선언
MqttClient client;
string clientId;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//메인폼이 로드되어서 사용자 눈에 딱 보였다!
//MQTT 브로커와 연결하는 부분
string BrokerAddress = "broker.emqx.io";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
richTextBox1.Text += "접속완료\n";
//접속이 완료된 위치
//Subscribe Topic 추가
string[] mytopic = { "NOCKANDA" };
byte[] qos = { 0 };
client.Subscribe(mytopic, qos);
richTextBox1.Text += "구독완료\n";
}
//MQTT이벤트 핸들러
void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
//DO SOMETHING..!
richTextBox1.Text += "[수신] " + ReceivedMessage + "\n";
string[] data = ReceivedMessage.Split(',');
if(data.Length == 3)
{
textBox1.Text = data[0];
textBox2.Text = data[1];
textBox3.Text = data[2];
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//사용자가 프로그램을 껐다!
//MQTT 연결 종료
client.Disconnect();
}
5.예제4에서 수신받은 온도와 습도값을 좀더 그럴싸하게 보이도록 하고 마무리하시오!


/* USER CODE BEGIN 0 */
char cmd1[] = "AT\r\n";
char cmd2[] = "ATE0\r\n";
char mode_set[] = "AT+CWMODE=1\r\n";
char ap_con[] = "AT+CWJAP=\"popcorn\",\"11213144\"\r\n";
char ap_discon[] = "AT+CWQAP\r\n";
char tcp_con[] = "AT+CIPSTART=\"TCP\",\"broker.emqx.io\",1883\r\n";
char data;
#define b_size 256
uint8_t ring_buffer[b_size];
int head = 0;
int tail = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
ring_buffer[head++] = data;
if(head == b_size) head = 0;
HAL_UART_Receive_IT(&huart1, &data, 1); //인터럽트 재시작~
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
//usart1에서 수신한 ring buffer안에 내용을 usart2에 출력한다!
if(head != tail){
char data = ring_buffer[tail];
HAL_UART_Transmit(&huart2, &data, 1, 100);
tail++;
if (tail == b_size) tail = 0;
}
}
#define delay_ms HAL_Delay
#define SYS_CLOCK 64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt & 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick->VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) { // 64MHz 보정
if (us > 1) {
uint32_t count = us * 7 - 6;
while (count--);
} else {
uint32_t count = 2;
while (count--);
}
}
union {
uint32_t data;
struct {
uint8_t temp_d;
uint8_t temp_i;
uint8_t rh_d;
uint8_t rh_i;
};
} DHT;
uint8_t DHT_read () {
uint8_t i, check_sum;
uint32_t start;
check_sum = 0;
DHT.data = 0;
GPIOC->CRL = (GPIOC->CRL&0xFFFFFF0F)|(7<<(1*4)); // Output Open-drain (Master send LOW signal)
delay_ms(18);
GPIOC->CRL= (GPIOC->CRL&0xFFFFFF0F)|(4<<(1*4)); // Floating input (Master send HIGH signal & data receive)
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 50) return 1; // 20~40us
}
start = micros();
while (!(GPIOC->IDR&(1<<1))) {
if (micros()-start > 120) return 2; // 80us
}
start = micros();
while (GPIOC->IDR&(1<<1)) {
if (micros()-start > 120) return 3; // 80us
}
for (i = 0; i < 32; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) DHT.data |= (0x80000000 >> i); // "0"=26~28us, "1"=70us
}
for (i = 0; i < 8; i++) {
while (!(GPIOC->IDR&(1<<1))); // 50us
start = micros();
while (GPIOC->IDR&(1<<1));
if (micros()-start > 50) check_sum |= (0x80 >> i);
}
if ((DHT.rh_i + DHT.rh_d + DHT.temp_i + DHT.temp_d) == check_sum) return 0;
else return 4;
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, &data, 1); //수신인터럽트
HAL_TIM_Base_Start_IT(&htim2); //타이머인터럽트
HAL_ADC_Start(&hadc1); //딱 한번만 호출
uint16_t adc_value0 = 0;
char u2_data;
uint8_t msg[256];
//연결 해제
HAL_UART_Transmit(&huart1,ap_discon,strlen(ap_discon),100);
HAL_UART_Transmit(&huart2,"AP DIS CON\r\n",12,100);
HAL_Delay(2000); //2초정도 기다리면 되겠지?
//연결
HAL_UART_Transmit(&huart1,ap_con,strlen(ap_con),100);
HAL_UART_Transmit(&huart2,"AP CONNECTING\r\n",15,100);
HAL_Delay(10000);
//브로커 접속
HAL_UART_Transmit(&huart1,tcp_con,strlen(tcp_con),100);
HAL_UART_Transmit(&huart2,"BROKER CONNECTING\r\n",19,100);
HAL_Delay(5000);
//MQTT 연결
uint8_t num1 = (HAL_GetTick()/1000) %10;
uint8_t num2 = (HAL_GetTick()/100) %10;
uint8_t num3 = (HAL_GetTick()/10) %10;
uint8_t num4 = HAL_GetTick() %10;
uint8_t MQTT_CONNECT[] = {0x10,0x14,0x00,0x04,'M','Q','T','T',0x04,0x02,0x00,0x3C,0x00,0x08,'N','O','C','K','0'+num1,'0'+num2,'0'+num3,'0'+num4};
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_CONNECT));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(1000);
HAL_UART_Transmit(&huart1,MQTT_CONNECT,sizeof(MQTT_CONNECT),100);
HAL_UART_Transmit(&huart2,"MQTT SET\r\n",10,100);
int msg_num = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
uint8_t error_no = DHT_read();
if(error_no == 0){ // 정상일 때 처리
float temp = 0;
float humi = 0;
temp = DHT.temp_i;
if (DHT.temp_d & 0x80) {
temp = -1 - temp;
}
temp += (DHT.temp_d & 0x0f) * 0.1;
humi = DHT.rh_i + DHT.rh_d * 0.1;
uint8_t MQTT_PUBLISH[] = {0x30,0x00,0x00,0x08,'N','O','C','K','A','N','D','A',0x00,0x00};
uint8_t MQTT_MSG[50];
sprintf(MQTT_MSG,"%d,%.2f,%.2f",msg_num,temp,humi);
msg_num++;
MQTT_PUBLISH[13] = strlen(MQTT_MSG);
MQTT_PUBLISH[1] = (sizeof(MQTT_PUBLISH)-2) +strlen(MQTT_MSG);
sprintf(msg, "AT+CIPSEND=%d\r\n", sizeof(MQTT_PUBLISH)+strlen(MQTT_MSG));
HAL_UART_Transmit(&huart1,msg,strlen(msg),100);
HAL_Delay(500);
HAL_UART_Transmit(&huart1,MQTT_PUBLISH,sizeof(MQTT_PUBLISH),100);
HAL_UART_Transmit(&huart1,MQTT_MSG,strlen(MQTT_MSG),100);
HAL_UART_Transmit(&huart2,"publish\r\n",9,100);
} else {
//측정실패
}
HAL_Delay(1500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
//전역으로 클래스선언
MqttClient client;
string clientId;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//메인폼이 로드되어서 사용자 눈에 딱 보였다!
//MQTT 브로커와 연결하는 부분
string BrokerAddress = "broker.emqx.io";
client = new MqttClient(BrokerAddress);
// register a callback-function (we have to implement, see below) which is called by the library when a message was received
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
// use a unique id as client id, each time we start the application
clientId = Guid.NewGuid().ToString();
client.Connect(clientId);
richTextBox1.Text += "접속완료\n";
//접속이 완료된 위치
//Subscribe Topic 추가
string[] mytopic = { "NOCKANDA" };
byte[] qos = { 0 };
client.Subscribe(mytopic, qos);
richTextBox1.Text += "구독완료\n";
}
//MQTT이벤트 핸들러
void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
string ReceivedMessage = Encoding.UTF8.GetString(e.Message, 2, e.Message.Length - 2);
//DO SOMETHING..!
string[] data = ReceivedMessage.Split(',');
if(data.Length == 3)
{
textBox1.Text = data[0];
textBox2.Text = data[1]; //온도
textBox3.Text = data[2]; //습도
float temp = float.Parse(data[1]);
float humi = float.Parse(data[2]);
aGauge1.Value = temp;
aGauge2.Value = humi;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
//사용자가 프로그램을 껐다!
//MQTT 연결 종료
client.Disconnect();
}반응형


